| @@ -1,268 +1,273 @@ | |||||
| <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |||||
| /* | |||||
| file: pks.php 車位在席模組 | |||||
| IVS -> 車號, 影像 | |||||
| 鼎高IVS傳送車號及影像檔 | |||||
| http://203.75.167.89/pks.html/cameras/sno/12112/ivsno/3/pksno/2016/io/KI/type/C/lpr/ABC1234/color/red/sq/5236 | |||||
| http://203.75.167.89/pks.html/cameras/sno/12119/ivsno/3/pksno/195/io/KO/type/C/lpr/NONE/color/red/sq/5236 | |||||
| sno: 場站編號(新北市圖書館:12118) | |||||
| ivsno: ivs編號, 每一支都是獨立編號(序號) | |||||
| pksno: 車位編號 | |||||
| io: KI:進車格, KO:出車格, KL:車牌 | |||||
| type: C:汽車, H:重機, M:機車 | |||||
| lpr: ABC1234(車號), 無:NONE | |||||
| color: red(紅色), 若無請用NONE(4個字) | |||||
| sq: 序號(查詢時參考用) | |||||
| http設定說明: | |||||
| method: POST | |||||
| 上傳圖檔名英數字, 副檔名為gif/jpg/png均可 | |||||
| 上傳圖檔欄位名稱為cars | |||||
| */ | |||||
| require_once(MQ_CLASS_FILE); | |||||
| class Pks extends CI_Controller | |||||
| { | |||||
| var $vars = array(); // 共用變數 | |||||
| function __construct() | |||||
| { | |||||
| // $this->time_start = microtime(true); | |||||
| parent::__construct(); | |||||
| ignore_user_abort(); // 接受client斷線, 繼續run | |||||
| $method_name = $this->router->fetch_method(); | |||||
| if ($method_name == 'cameras') | |||||
| { | |||||
| ob_end_clean(); | |||||
| ignore_user_abort(); | |||||
| ob_start(); | |||||
| header('Connection: close'); | |||||
| header('Content-Length: ' . ob_get_length()); | |||||
| ob_end_flush(); | |||||
| flush(); | |||||
| } | |||||
| $this->vars['date_time'] = date('Y-m-d H:i:s'); // 格式化時間(2015-10-12 14:36:21) | |||||
| $this->vars['time_num'] = str_replace(array('-', ':', ' '), '', $this->vars['date_time']); //數字化時間(20151012143621) | |||||
| $this->vars['date_num'] = substr($this->vars['time_num'], 0, 8); // 數字化日期(20151012) | |||||
| $this->vars['station_no'] = STATION_NO; // 本站編號 | |||||
| // ----- 程式開發階段log設定 ----- | |||||
| if (@ENVIRONMENT == 'development') | |||||
| { | |||||
| ini_set('display_errors', '1'); | |||||
| //error_reporting(E_ALL ^ E_NOTICE); | |||||
| error_reporting(E_ALL); | |||||
| } | |||||
| set_error_handler(array($this, 'error_handler'), E_ALL); // 資料庫異動需做log | |||||
| // mqtt subscribe | |||||
| $this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_PORT, uniqid()); | |||||
| if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); } | |||||
| // ----- 定義常數(路徑, cache秒數) ----- | |||||
| define('APP_VERSION', '100'); // 版本號 | |||||
| define('MAX_AGE', 604800); // cache秒數, 此定義1個月 | |||||
| define('APP_NAME', 'pks'); // 應用系統名稱 | |||||
| define('PAGE_PATH', APP_BASE.'ci_application/views/'.APP_NAME.'/'); // path of views | |||||
| define('SERVER_URL', 'http://'.(isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost').'/'); // URL | |||||
| define('APP_URL', SERVER_URL.APP_NAME.'.html/'); // controller路徑 | |||||
| define('WEB_URL', SERVER_URL.APP_NAME.'/'); // 網頁路徑 | |||||
| define('WEB_LIB', SERVER_URL.'/libs/'); // 網頁lib | |||||
| define('BOOTSTRAPS', WEB_LIB.'bootstrap_sb/'); // bootstrap lib | |||||
| define('LOG_PATH', FILE_BASE.APP_NAME.'/logs/'); // log path name | |||||
| define('LOG_FILE', FILE_BASE.APP_NAME.'/logs/pks.'); // log file name | |||||
| $this->load->model('pks_model'); | |||||
| $this->pks_model->init($this->vars); | |||||
| } | |||||
| // 發生錯誤時集中在此處理 | |||||
| public function error_handler($errno, $errstr, $errfile, $errline, $errcontext) | |||||
| { | |||||
| $log_msg = explode('://', $errstr); | |||||
| if (count($log_msg) > 1) | |||||
| { | |||||
| $log_file = $log_msg[0]; | |||||
| $str = date('H:i:s')."|{$log_msg[1]}|{$errfile}|{$errline}|{$errno}\n"; | |||||
| } | |||||
| else | |||||
| { | |||||
| $log_file = APP_NAME; | |||||
| $str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n"; | |||||
| } | |||||
| error_log($str, 3, LOG_PATH.$log_file . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名 | |||||
| } | |||||
| // 顯示靜態網頁(html檔) | |||||
| protected function show_page($page_name, &$data = null) | |||||
| { | |||||
| $page_file = PAGE_PATH.$page_name.'.php'; | |||||
| $last_modified_time = filemtime($page_file); | |||||
| // 若檔案修改時間沒有異動, 或版本無異動, 通知瀏覽器使用cache, 不再下傳網頁 | |||||
| // header('Cache-Control:max-age='.MAX_AGE); // cache 1個月 | |||||
| header('Last-Modified: '.gmdate('D, d M Y H:i:s', $last_modified_time).' GMT'); | |||||
| header('Etag: '. APP_VERSION); | |||||
| header('Cache-Control: public'); | |||||
| if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == APP_VERSION && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time) | |||||
| { | |||||
| header('HTTP/1.1 304 Not Modified'); | |||||
| } | |||||
| else | |||||
| { | |||||
| $this->load->view(APP_NAME.'/'.$page_name, $data); | |||||
| } | |||||
| } | |||||
| public function parked() | |||||
| { | |||||
| $data['group_id'] = $this->uri->segment(3); | |||||
| $data['init_value'] = $this->uri->segment(4); | |||||
| // $data['client_id'] = uniqid(); | |||||
| // $data['mqtt_ip'] = '192.168.10.201'; | |||||
| // $data['port_no'] = 8000; | |||||
| $this->load->view(APP_NAME.'/parked', $data); | |||||
| } | |||||
| // 樓層平面圖 | |||||
| // http://203.75.167.89/parkingquery.html/floor_map | |||||
| public function floor_map() | |||||
| { | |||||
| /* | |||||
| header('Access-Control-Allow-Origin: *'); | |||||
| header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); | |||||
| header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept'); | |||||
| */ | |||||
| $this->load->view("parkingquery/floor_map"); | |||||
| } | |||||
| // response http | |||||
| protected function http_return($return_code, $type) | |||||
| { | |||||
| if ($type == 'text') echo $return_code; | |||||
| else echo json_encode($return_code, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| // 顯示logs | |||||
| public function show_logs() | |||||
| { | |||||
| $lines = $this->uri->segment(3); // 顯示行數 | |||||
| if (empty($lines)) $lines = 40; // 無行數參數, 預設為40行 | |||||
| // echo '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><pre style="white-space: pre-wrap;">'; | |||||
| echo '<html lang="zh-TW"><body><pre style="white-space: pre-wrap;">'; | |||||
| if (PHP_OS == 'Linux') | |||||
| passthru('/usr/bin/tail -n ' . $lines . ' ' . LOG_FILE); // 利用linux指令顯示倒數幾行的logs內容 | |||||
| else | |||||
| passthru('d:/afiles/bin/unix_cmd/tail.exe -n ' . $lines . ' ' . LOG_FILE); | |||||
| echo "\n----- " . LOG_FILE . ' -----'; | |||||
| echo '</pre></body></html>'; | |||||
| } | |||||
| // IVS -> 車號, 影像 | |||||
| /* | |||||
| IVS -> 車號, 影像 | |||||
| 鼎高IVS傳送車號及影像檔 | |||||
| http://203.75.167.89/pks.html/cameras/sno/12119/ivsno/3/pksno/102/io/KI/type/C/lpr/ABC1234/color/red/sq/5236 | |||||
| sno: 場站編號(新北市圖書館:12118) | |||||
| ivsno: ivs編號, 每一支都是獨立編號(序號) | |||||
| pksno: 車位編號 | |||||
| io: KI:進車格, KO:出車格, KL:車牌辨識 | |||||
| type: C:汽車, H:重機, M:機車 | |||||
| lpr: ABC1234(車號) | |||||
| color: red(紅色), 若無請用NONE(4個字) | |||||
| sq: 序號(查詢時參考用) | |||||
| http設定說明: | |||||
| method: POST | |||||
| 上傳圖檔名英數字, 副檔名為gif/jpg/png均可 | |||||
| 上傳圖檔欄位名稱為cars | |||||
| */ | |||||
| public function cameras() | |||||
| { | |||||
| $parms = $this->uri->uri_to_assoc(3); | |||||
| trigger_error('在席參數傳入:'.print_r($parms, true)); | |||||
| // array_map('unlink', glob(PKS_PIC."pks-{$parms['pksno']}-*")); | |||||
| /* | |||||
| // 車入格後的車牌辨識(lpr), 傅送圖檔 | |||||
| if ($parms['io'] == 'KL') | |||||
| { | |||||
| array_map('unlink', glob(PKS_PIC."pks-{$parms['pksno']}-*.jpg")); // 刪除舊照片 | |||||
| $config['upload_path'] = PKS_PIC; | |||||
| $config['allowed_types'] = 'gif|jpg|png'; | |||||
| // ex. pks-2016-1625AB-1-2015080526.jpg -> pks-車位編號-車號-設備編號-時間.jpg | |||||
| $config['file_name'] = "pks-{$parms['pksno']}-{$parms['lpr']}-{$parms['ivsno']}-{$this->vars['time_num']}.jpg"; | |||||
| $this->load->library('upload', $config); | |||||
| $parms['pic_name'] = $config['file_name']; | |||||
| if($this->upload->do_upload('cars')) | |||||
| { | |||||
| // 若無錯誤,則上傳檔案 | |||||
| $file = $this->upload->data('cars'); | |||||
| } | |||||
| else | |||||
| { | |||||
| trigger_error('入席傳檔錯誤:'. print_r($parms, true)); | |||||
| } | |||||
| } | |||||
| */ | |||||
| $this->pks_model->pksio($parms); // 車輛進出車格資料庫處理 | |||||
| exit; | |||||
| } | |||||
| // 重新計算 | |||||
| // http://203.75.167.89/pks.html/reculc/ | |||||
| public function reculc() | |||||
| { | |||||
| $this->pks_model->reculc(); | |||||
| } | |||||
| // 取得所有車位狀態資訊 | |||||
| // http://203.75.167.89/pks.html/query_station_status/12112 | |||||
| public function query_station_status() | |||||
| { | |||||
| $station_no = $this->uri->segment(3); | |||||
| $data = $this->pks_model->query_station_status($station_no); | |||||
| echo json_encode($data, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| // 取得車位資訊 | |||||
| // http://203.75.167.89/pks.html/query_station_pks/12112/2021 | |||||
| public function query_station_pks(){ | |||||
| $station_no = $this->uri->segment(3); | |||||
| $pksno = $this->uri->segment(4); | |||||
| $data = $this->pks_model->query_station_pks($station_no, $pksno); | |||||
| echo json_encode($data, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| // 車位狀態資訊圖 | |||||
| // http://203.75.167.89/pks.html/status_map | |||||
| public function status_map() | |||||
| { | |||||
| $this->show_page("status_map"); | |||||
| } | |||||
| } | |||||
| <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |||||
| /* | |||||
| file: pks.php 車位在席模組 | |||||
| IVS -> 車號, 影像 | |||||
| 鼎高IVS傳送車號及影像檔 | |||||
| http://203.75.167.89/pks.html/cameras/sno/12112/ivsno/3/pksno/2016/io/KI/type/C/lpr/ABC1234/color/red/sq/5236 | |||||
| http://203.75.167.89/pks.html/cameras/sno/12119/ivsno/3/pksno/195/io/KO/type/C/lpr/NONE/color/red/sq/5236 | |||||
| sno: 場站編號(新北市圖書館:12118) | |||||
| ivsno: ivs編號, 每一支都是獨立編號(序號) | |||||
| pksno: 車位編號 | |||||
| io: KI:進車格, KO:出車格, KL:車牌 | |||||
| type: C:汽車, H:重機, M:機車 | |||||
| lpr: ABC1234(車號), 無:NONE | |||||
| color: red(紅色), 若無請用NONE(4個字) | |||||
| sq: 序號(查詢時參考用) | |||||
| http設定說明: | |||||
| method: POST | |||||
| 上傳圖檔名英數字, 副檔名為gif/jpg/png均可 | |||||
| 上傳圖檔欄位名稱為cars | |||||
| */ | |||||
| require_once(MQ_CLASS_FILE); | |||||
| class Pks extends CI_Controller | |||||
| { | |||||
| var $vars = array(); // 共用變數 | |||||
| function __construct() | |||||
| { | |||||
| // $this->time_start = microtime(true); | |||||
| parent::__construct(); | |||||
| ignore_user_abort(); // 接受client斷線, 繼續run | |||||
| $method_name = $this->router->fetch_method(); | |||||
| if ($method_name == 'cameras') | |||||
| { | |||||
| ob_end_clean(); | |||||
| ignore_user_abort(); | |||||
| ob_start(); | |||||
| header('Connection: close'); | |||||
| header('Content-Length: ' . ob_get_length()); | |||||
| ob_end_flush(); | |||||
| flush(); | |||||
| } | |||||
| $this->vars['date_time'] = date('Y-m-d H:i:s'); // 格式化時間(2015-10-12 14:36:21) | |||||
| $this->vars['time_num'] = str_replace(array('-', ':', ' '), '', $this->vars['date_time']); //數字化時間(20151012143621) | |||||
| $this->vars['date_num'] = substr($this->vars['time_num'], 0, 8); // 數字化日期(20151012) | |||||
| $this->vars['station_no'] = STATION_NO; // 本站編號 | |||||
| // ----- 程式開發階段log設定 ----- | |||||
| if (@ENVIRONMENT == 'development') | |||||
| { | |||||
| ini_set('display_errors', '1'); | |||||
| //error_reporting(E_ALL ^ E_NOTICE); | |||||
| error_reporting(E_ALL); | |||||
| } | |||||
| set_error_handler(array($this, 'error_handler'), E_ALL); // 資料庫異動需做log | |||||
| // mqtt subscribe | |||||
| $this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_PORT, uniqid()); | |||||
| if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); } | |||||
| // ----- 定義常數(路徑, cache秒數) ----- | |||||
| define('APP_VERSION', '100'); // 版本號 | |||||
| define('MAX_AGE', 604800); // cache秒數, 此定義1個月 | |||||
| define('APP_NAME', 'pks'); // 應用系統名稱 | |||||
| define('PAGE_PATH', APP_BASE.'ci_application/views/'.APP_NAME.'/'); // path of views | |||||
| define('SERVER_URL', 'http://'.(isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost').'/'); // URL | |||||
| define('APP_URL', SERVER_URL.APP_NAME.'.html/'); // controller路徑 | |||||
| define('WEB_URL', SERVER_URL.APP_NAME.'/'); // 網頁路徑 | |||||
| define('WEB_LIB', SERVER_URL.'/libs/'); // 網頁lib | |||||
| define('BOOTSTRAPS', WEB_LIB.'bootstrap_sb/'); // bootstrap lib | |||||
| define('LOG_PATH', FILE_BASE.APP_NAME.'/logs/'); // log path name | |||||
| define('LOG_FILE', FILE_BASE.APP_NAME.'/logs/pks.'); // log file name | |||||
| $this->load->model('pks_model'); | |||||
| $this->pks_model->init($this->vars); | |||||
| } | |||||
| // 發生錯誤時集中在此處理 | |||||
| public function error_handler($errno, $errstr, $errfile, $errline, $errcontext) | |||||
| { | |||||
| $log_msg = explode('://', $errstr); | |||||
| if (count($log_msg) > 1) | |||||
| { | |||||
| $log_file = $log_msg[0]; | |||||
| $str = date('H:i:s')."|{$log_msg[1]}|{$errfile}|{$errline}|{$errno}\n"; | |||||
| } | |||||
| else | |||||
| { | |||||
| $log_file = APP_NAME; | |||||
| $str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n"; | |||||
| } | |||||
| error_log($str, 3, LOG_PATH.$log_file . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名 | |||||
| } | |||||
| // 顯示靜態網頁(html檔) | |||||
| protected function show_page($page_name, &$data = null) | |||||
| { | |||||
| $page_file = PAGE_PATH.$page_name.'.php'; | |||||
| $last_modified_time = filemtime($page_file); | |||||
| // 若檔案修改時間沒有異動, 或版本無異動, 通知瀏覽器使用cache, 不再下傳網頁 | |||||
| // header('Cache-Control:max-age='.MAX_AGE); // cache 1個月 | |||||
| header('Last-Modified: '.gmdate('D, d M Y H:i:s', $last_modified_time).' GMT'); | |||||
| header('Etag: '. APP_VERSION); | |||||
| header('Cache-Control: public'); | |||||
| if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == APP_VERSION && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time) | |||||
| { | |||||
| header('HTTP/1.1 304 Not Modified'); | |||||
| } | |||||
| else | |||||
| { | |||||
| $this->load->view(APP_NAME.'/'.$page_name, $data); | |||||
| } | |||||
| } | |||||
| public function parked() | |||||
| { | |||||
| $data['group_id'] = $this->uri->segment(3); | |||||
| $data['init_value'] = $this->uri->segment(4); | |||||
| // $data['client_id'] = uniqid(); | |||||
| // $data['mqtt_ip'] = '192.168.10.201'; | |||||
| // $data['port_no'] = 8000; | |||||
| $this->load->view(APP_NAME.'/parked', $data); | |||||
| } | |||||
| // 樓層平面圖 | |||||
| // http://203.75.167.89/parkingquery.html/floor_map | |||||
| public function floor_map() | |||||
| { | |||||
| /* | |||||
| header('Access-Control-Allow-Origin: *'); | |||||
| header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); | |||||
| header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept'); | |||||
| */ | |||||
| $this->load->view("parkingquery/floor_map"); | |||||
| } | |||||
| // response http | |||||
| protected function http_return($return_code, $type) | |||||
| { | |||||
| if ($type == 'text') echo $return_code; | |||||
| else echo json_encode($return_code, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| // 顯示logs | |||||
| public function show_logs() | |||||
| { | |||||
| $lines = $this->uri->segment(3); // 顯示行數 | |||||
| if (empty($lines)) $lines = 40; // 無行數參數, 預設為40行 | |||||
| // echo '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><pre style="white-space: pre-wrap;">'; | |||||
| echo '<html lang="zh-TW"><body><pre style="white-space: pre-wrap;">'; | |||||
| if (PHP_OS == 'Linux') | |||||
| passthru('/usr/bin/tail -n ' . $lines . ' ' . LOG_FILE); // 利用linux指令顯示倒數幾行的logs內容 | |||||
| else | |||||
| passthru('d:/afiles/bin/unix_cmd/tail.exe -n ' . $lines . ' ' . LOG_FILE); | |||||
| echo "\n----- " . LOG_FILE . ' -----'; | |||||
| echo '</pre></body></html>'; | |||||
| } | |||||
| // IVS -> 車號, 影像 | |||||
| /* | |||||
| IVS -> 車號, 影像 | |||||
| 鼎高IVS傳送車號及影像檔 | |||||
| http://203.75.167.89/pks.html/cameras/sno/12119/ivsno/3/pksno/102/io/KI/type/C/lpr/ABC1234/color/red/sq/5236 | |||||
| sno: 場站編號(新北市圖書館:12118) | |||||
| ivsno: ivs編號, 每一支都是獨立編號(序號) | |||||
| pksno: 車位編號 | |||||
| io: KI:進車格, KO:出車格, KL:車牌辨識 | |||||
| type: C:汽車, H:重機, M:機車 | |||||
| lpr: ABC1234(車號) | |||||
| color: red(紅色), 若無請用NONE(4個字) | |||||
| sq: 序號(查詢時參考用) | |||||
| http設定說明: | |||||
| method: POST | |||||
| 上傳圖檔名英數字, 副檔名為gif/jpg/png均可 | |||||
| 上傳圖檔欄位名稱為cars | |||||
| */ | |||||
| public function cameras() | |||||
| { | |||||
| $parms = $this->uri->uri_to_assoc(3); | |||||
| // 調整 pksno 為 pks 格式 | |||||
| $parms['pksno'] = intval(implode('', explode('F_', $parms['pksno']))); | |||||
| trigger_error('在席參數傳入:'.print_r($parms, true)); | |||||
| // array_map('unlink', glob(PKS_PIC."pks-{$parms['pksno']}-*")); | |||||
| /* | |||||
| // 車入格後的車牌辨識(lpr), 傅送圖檔 | |||||
| if ($parms['io'] == 'KL') | |||||
| { | |||||
| array_map('unlink', glob(PKS_PIC."pks-{$parms['pksno']}-*.jpg")); // 刪除舊照片 | |||||
| $config['upload_path'] = PKS_PIC; | |||||
| $config['allowed_types'] = 'gif|jpg|png'; | |||||
| // ex. pks-2016-1625AB-1-2015080526.jpg -> pks-車位編號-車號-設備編號-時間.jpg | |||||
| $config['file_name'] = "pks-{$parms['pksno']}-{$parms['lpr']}-{$parms['ivsno']}-{$this->vars['time_num']}.jpg"; | |||||
| $this->load->library('upload', $config); | |||||
| $parms['pic_name'] = $config['file_name']; | |||||
| if($this->upload->do_upload('cars')) | |||||
| { | |||||
| // 若無錯誤,則上傳檔案 | |||||
| $file = $this->upload->data('cars'); | |||||
| } | |||||
| else | |||||
| { | |||||
| trigger_error('入席傳檔錯誤:'. print_r($parms, true)); | |||||
| } | |||||
| } | |||||
| */ | |||||
| $this->pks_model->pksio($parms); // 車輛進出車格資料庫處理 | |||||
| exit; | |||||
| } | |||||
| // 重新計算 | |||||
| // http://203.75.167.89/pks.html/reculc/ | |||||
| public function reculc() | |||||
| { | |||||
| $this->pks_model->reculc(); | |||||
| } | |||||
| // 取得所有車位狀態資訊 | |||||
| // http://203.75.167.89/pks.html/query_station_status/12112 | |||||
| public function query_station_status() | |||||
| { | |||||
| $station_no = $this->uri->segment(3); | |||||
| $data = $this->pks_model->query_station_status($station_no); | |||||
| echo json_encode($data, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| // 取得車位資訊 | |||||
| // http://203.75.167.89/pks.html/query_station_pks/12112/2021 | |||||
| public function query_station_pks(){ | |||||
| $station_no = $this->uri->segment(3); | |||||
| $pksno = $this->uri->segment(4); | |||||
| $data = $this->pks_model->query_station_pks($station_no, $pksno); | |||||
| echo json_encode($data, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| // 車位狀態資訊圖 | |||||
| // http://203.75.167.89/pks.html/status_map | |||||
| public function status_map() | |||||
| { | |||||
| $this->show_page("status_map"); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,112 @@ | |||||
| <?php | |||||
| /* | |||||
| file: qcar2.php 查車系統2 | |||||
| */ | |||||
| if (!defined('BASEPATH')) exit('No direct script access allowed'); | |||||
| // ----- 定義常數(路徑, cache秒數) ----- | |||||
| define('APP_VERSION', '100'); // 版本號 | |||||
| define('MAX_AGE', 604800); // cache秒數, 此定義1個月 | |||||
| define('APP_NAME', 'qcar2'); // 應用系統名稱 | |||||
| define('PAGE_PATH', APP_BASE.'ci_application/views/'.APP_NAME.'/'); // path of views | |||||
| define('SERVER_URL', 'http://'.(isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost').'/'); // URL | |||||
| define('APP_URL', SERVER_URL.APP_NAME.'.html/'); // controller路徑 | |||||
| define('WEB_URL', SERVER_URL.APP_NAME.'/'); // 網頁路徑 | |||||
| define('WEB_LIB', SERVER_URL.'libs/'); // 網頁lib | |||||
| define('BOOTSTRAPS', WEB_LIB.'bootstrap_sb/'); // bootstrap lib | |||||
| define('LOG_PATH', FILE_BASE.APP_NAME.'/logs/'); // log path | |||||
| class Qcar2 extends CI_Controller | |||||
| { | |||||
| var $vars = array(); // 共用變數 | |||||
| function __construct() | |||||
| { | |||||
| parent::__construct(); | |||||
| // ----- 程式開發階段log設定 ----- | |||||
| if (@ENVIRONMENT == 'development') | |||||
| { | |||||
| ini_set('display_errors', '1'); | |||||
| //error_reporting(E_ALL ^ E_NOTICE); | |||||
| error_reporting(E_ALL); | |||||
| } | |||||
| set_error_handler(array($this, 'error_handler'), E_ALL); // 資料庫異動需做log | |||||
| $this->load->model('qcar2_model'); | |||||
| } | |||||
| // 發生錯誤時集中在此處理 | |||||
| public function error_handler($errno, $errstr, $errfile, $errline, $errcontext) | |||||
| { | |||||
| $str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n"; | |||||
| //error_log($str, 3, $log_file . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名 | |||||
| error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名 | |||||
| } | |||||
| // 顯示靜態網頁(html檔) | |||||
| protected function show_page($page_name, &$data = null) | |||||
| { | |||||
| $page_file = PAGE_PATH.$page_name.'.php'; | |||||
| $last_modified_time = filemtime($page_file); | |||||
| // 若檔案修改時間沒有異動, 或版本無異動, 通知瀏覽器使用cache, 不再下傳網頁 | |||||
| // header('Cache-Control:max-age='.MAX_AGE); // cache 1個月 | |||||
| header('Last-Modified: '.gmdate('D, d M Y H:i:s', $last_modified_time).' GMT'); | |||||
| header('Etag: '. APP_VERSION); | |||||
| header('Cache-Control: public'); | |||||
| if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == APP_VERSION && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time) | |||||
| { | |||||
| header('HTTP/1.1 304 Not Modified'); | |||||
| } | |||||
| else | |||||
| { | |||||
| $this->load->view(APP_NAME.'/'.$page_name, $data); | |||||
| } | |||||
| } | |||||
| public function index() | |||||
| { | |||||
| $this->show_page('main_page'); | |||||
| } | |||||
| // 顯示logs | |||||
| public function show_logs() | |||||
| { | |||||
| $lines = $this->uri->segment(3); // 顯示行數 | |||||
| if (empty($lines)) $lines = 40; // 無行數參數, 預設為40行 | |||||
| // echo '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><pre style="white-space: pre-wrap;">'; | |||||
| echo '<html lang="zh-TW"><body><pre style="white-space: pre-wrap;">'; | |||||
| passthru('/usr/bin/tail -n ' . $lines . ' ' . LOG_FILE); // 利用linux指令顯示倒數幾行的logs內容 | |||||
| echo "\n----- " . LOG_FILE . ' -----'; | |||||
| echo '</pre></body></html>'; | |||||
| } | |||||
| // 車位查詢 | |||||
| public function q_pks() | |||||
| { | |||||
| $lpr = $this->input->post('lpr', true); | |||||
| $data = $this->qcar2_model->q_pks($lpr); | |||||
| echo json_encode($data, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| // 取得進場資訊 (模糊比對) | |||||
| public function q_fuzzy_pks() | |||||
| { | |||||
| $input = $this->input->post('fuzzy_input', true); | |||||
| $data = $this->qcar2_model->q_fuzzy_pks($input); | |||||
| echo json_encode($data, JSON_UNESCAPED_UNICODE); | |||||
| } | |||||
| } | |||||
| @@ -1,356 +1,359 @@ | |||||
| <?php | |||||
| /* | |||||
| file: pks_model.php 車位在席資料庫處理模組 | |||||
| */ | |||||
| class Pks_model extends CI_Model | |||||
| { | |||||
| var $vars = array(); | |||||
| function __construct() | |||||
| { | |||||
| parent::__construct(); | |||||
| $this->load->database(); | |||||
| } | |||||
| public function init($vars) | |||||
| { | |||||
| $this->vars = $vars; | |||||
| } | |||||
| // 車輛進出傳入車牌號碼 | |||||
| public function pksio($parms) | |||||
| { | |||||
| switch($parms['io']) | |||||
| { | |||||
| case 'KL': // 車輛入席車辨(lpr)及圖檔 | |||||
| if ($parms['lpr'] == 'NONE') // 在席車辨失敗, 不處理 | |||||
| { | |||||
| trigger_error('在席車辨失敗' . print_r($parms, true)); | |||||
| return false; | |||||
| } | |||||
| // 讀取在席資料(pks) | |||||
| $rows_pks = $this->db | |||||
| ->select('cario_no, lpr, status, confirms') | |||||
| ->from('pks') | |||||
| ->where(array('pksno' => $parms['pksno'], 'station_no' => $this->vars['station_no'])) | |||||
| ->limit(1) | |||||
| ->get() | |||||
| ->row_array(); | |||||
| trigger_error('KL read pks:'.print_r($rows_pks, true)); | |||||
| // 如果已經人工確認或之前已比對有入場資料者, 則重覆再送來的車辨不予理會 | |||||
| if ($rows_pks['confirms'] == 1 || $rows_pks['lpr'] == $parms['lpr']) | |||||
| { | |||||
| trigger_error('KL ignored:'.$rows_pks['lpr']); | |||||
| return false; | |||||
| } | |||||
| /* | |||||
| if ($rows_pks['cario_no'] != 0 || $rows_pks['confirms'] == 1 || $rows_pks['lpr'] == $parms['lpr']) | |||||
| { | |||||
| trigger_error('人工已確認或車號相同不更新pks:'.$rows_pks['lpr']); | |||||
| return false; | |||||
| } | |||||
| */ | |||||
| // 讀取進場時間, 如讀不到資料, 以目前時間取代(add by TZUSS 2016-02-23) | |||||
| $rows_cario = $this->db | |||||
| ->select('cario_no, in_time') | |||||
| ->from('cario') | |||||
| ->where(array('in_out' => 'CI', 'obj_id' => $parms['lpr'], 'finished' => 0, 'err' => 0, 'station_no' => $this->vars['station_no'])) | |||||
| ->order_by('cario_no', 'desc') | |||||
| ->limit(1) | |||||
| ->get() | |||||
| ->row_array(); | |||||
| if (!empty($rows_cario['cario_no'])) // 有入場資料 | |||||
| { | |||||
| $cario_no = $rows_cario['cario_no']; // 入場序號 | |||||
| $in_time = $rows_cario['in_time']; | |||||
| // 在席與入場資料相符, 分別在cario與pks記錄之 | |||||
| $data_cario = array | |||||
| ( | |||||
| 'pksno' => $parms['pksno'], | |||||
| 'pks_time' => date('Y-m-d H:i:s') | |||||
| ); | |||||
| $this->db->update('cario', $data_cario, array('cario_no' => $cario_no, 'station_no' => $this->vars['station_no'])); | |||||
| } | |||||
| else // 查無入場資料, 即時通知 | |||||
| { | |||||
| $cario_no = 0; | |||||
| $in_time = date('Y-m-d H:i:s'); | |||||
| $jdata = json_encode(array | |||||
| ( | |||||
| 'pksno' => $parms['pksno'], | |||||
| 'lpr' => $parms['lpr'], | |||||
| 'in_time' => $in_time, | |||||
| 'pic_name' => $parms['pic_name'] | |||||
| ), JSON_UNESCAPED_UNICODE); | |||||
| // $this->vars['mqtt']-lish('PKS_WITHOUT_IN', "{$jdata}", 0); // 待web完成 ??? | |||||
| trigger_error('在席無進場資料:'. print_r($parms, true)); | |||||
| } | |||||
| // 車入格後的車牌辨識(lpr), 傅送圖檔 | |||||
| array_map('unlink', glob(PKS_PIC."pks-{$parms['pksno']}-*.jpg")); // 刪除舊照片 | |||||
| $config['upload_path'] = PKS_PIC; | |||||
| $config['allowed_types'] = 'gif|jpg|png'; | |||||
| // ex. pks-2016-1625AB-1-2015080526.jpg -> pks-車位編號-車號-設備編號-時間.jpg | |||||
| $config['file_name'] = "pks-{$parms['pksno']}-{$parms['lpr']}-{$parms['ivsno']}-{$this->vars['time_num']}.jpg"; | |||||
| $this->load->library('upload', $config); | |||||
| $parms['pic_name'] = $config['file_name']; | |||||
| if($this->upload->do_upload('cars')) | |||||
| { | |||||
| // 若無錯誤,則上傳檔案 | |||||
| $file = $this->upload->data('cars'); | |||||
| } | |||||
| else | |||||
| { | |||||
| trigger_error('入席傳檔錯誤:'. print_r($parms, true)); | |||||
| } | |||||
| $data = array | |||||
| ( | |||||
| 'cario_no' => $cario_no, | |||||
| 'lpr' => $parms['lpr'], | |||||
| 'status' => 'LR', // 車格佔用並有車號 | |||||
| 'confirms' => 0, // 預設人工未確認 | |||||
| 'pic_name' => $parms['pic_name'], | |||||
| 'in_time' => $in_time | |||||
| ); | |||||
| // 車號及照片檔名填入資料庫內 | |||||
| $this->db->update('pks', $data, array('pksno' => $parms['pksno'], 'station_no' => $this->vars['station_no'])); | |||||
| break; | |||||
| case 'KI': // 車輛入席, 各區空車位與佔位各加減1 | |||||
| $rows = $this->db->select('status') | |||||
| ->from('pks') | |||||
| ->where(array('pksno' => $parms['pksno'], 'station_no' => $this->vars['station_no'])) | |||||
| ->get() | |||||
| ->row_array(); | |||||
| // if (!empty($rows['status']) && $rows['status'] == 'LR') break; // 仍有車在席, 不應再有KI, ignore | |||||
| if (!empty($rows['status']) && $rows['status'] == 'LR') return true; // 仍有車在席, 不應再有KI, ignore | |||||
| $data = array | |||||
| ( | |||||
| 'cario_no' => 0, | |||||
| 'lpr' => '', | |||||
| 'status' => 'OC', // 車格佔用但尚無車號 | |||||
| 'confirms' => 0, | |||||
| 'pic_name' => '', | |||||
| 'in_time' => null | |||||
| ); | |||||
| $this->db->update('pks', $data, array('pksno' => $parms['pksno'], 'station_no' => $this->vars['station_no'])); | |||||
| break; | |||||
| case 'KO': // 車輛離席, 各區空車位與佔位各加減1 | |||||
| $data = array | |||||
| ( | |||||
| 'cario_no' => 0, | |||||
| 'lpr' => '', | |||||
| 'status' => 'VA', // 車格佔用但尚無車號 | |||||
| 'confirms' => 0, | |||||
| 'pic_name' => '', | |||||
| 'in_time' => null | |||||
| ); | |||||
| $this->db->update('pks', $data, array('pksno' => $parms['pksno'], 'station_no' => $this->vars['station_no'])); | |||||
| break; | |||||
| } | |||||
| /* | |||||
| // 找出與與此車位相關的群組 | |||||
| $sql = "select group_id, tot, renum | |||||
| from pks_groups | |||||
| where group_id in | |||||
| (select group_id from pks_group_member where station_no = {$this->vars['station_no']} and pksno = {$parms['pksno']})"; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| foreach ($retults as $rows) | |||||
| { | |||||
| // 計算群組異動後的空車位數, 先讀出已停車位數 | |||||
| $sql = "select count(*) as parked from pks where status != 'VA' and pksno in (select pksno from pks_group_member where group_id = '{$rows['group_id']}')"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $group_va = $rows['tot'] + $rows['renum'] - $row_group['parked']; // 群組空車位數 | |||||
| $this->db->update('pks_groups', array('parked' => $row_group['parked'], 'availables' => $group_va), array('group_id' => $rows['group_id'])); | |||||
| get_headers("http://192.168.51.15/set_num.php?group_id={$rows['group_id']}&num={$group_va}"); | |||||
| // $this->vars['mqtt']->publish("VA-{$rows['group_id']}", "{$group_va}", 0); // 送出剩餘車位數給字幕機 | |||||
| // 總車位數暫無需處理 | |||||
| } | |||||
| */ | |||||
| // 找出與與此車位相關的群組 | |||||
| $sql = "select group_id, tot, renum, availables | |||||
| from pks_groups | |||||
| where group_id in | |||||
| (select group_id from pks_group_member where station_no = {$this->vars['station_no']} and pksno = {$parms['pksno']})"; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| foreach ($retults as $rows) | |||||
| { | |||||
| // 計算群組異動後的空車位數, 先讀出已停車位數 | |||||
| $sql = "select count(*) as parked from pks where status != 'VA' and pksno in (select pksno from pks_group_member where group_id = '{$rows['group_id']}')"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $group_va = $rows['tot'] + $rows['renum'] - $row_group['parked']; // 群組空車位數 | |||||
| // 有變動才處理更新 | |||||
| if($rows['availables'] != $group_va) | |||||
| { | |||||
| // 防止負值 | |||||
| if($group_va < 0){ | |||||
| $group_va = 0; | |||||
| } | |||||
| $group_va_pad = str_pad($group_va, 3, '0', STR_PAD_LEFT); // 補零 | |||||
| $this->db->update('pks_groups', array('parked' => $row_group['parked'], 'availables' => $group_va), array('group_id' => $rows['group_id'])); | |||||
| $this->vars['mqtt']->publish(MQ_TOPIC_SUBLEVEL, "{$rows['group_id']},{$group_va_pad}", 0); // 送出剩餘車位數給字幕機 | |||||
| // 總車位數暫無需處理 | |||||
| // 七樓無在席, 手動或用猜的 | |||||
| /* | |||||
| $f7_total = 74; | |||||
| $sql = "select renum from pks_groups where group_id = 'F7'"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $f7_renum = $row_group['renum']; | |||||
| $total_parked_sql = "select count(cario_no) as parked | |||||
| from cario where | |||||
| cario.in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY) | |||||
| and cario.finished = 0 | |||||
| and cario.err = 0 | |||||
| and cario.in_out = 'CI' | |||||
| and cario.out_time is null"; | |||||
| $total_parked_row_group = $this->db->query($total_parked_sql)->row_array(); | |||||
| $sql = "select count(pksno) as parked from pks where status != 'VA'"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $f7_mqtt = $total_parked_row_group['parked'] - $row_group['parked']; | |||||
| if($f7_mqtt > $f7_total){ | |||||
| $f7_mqtt = $f7_total; | |||||
| }else if($f7_mqtt <= 0){ | |||||
| $f7_mqtt = 0; | |||||
| } | |||||
| $this->db->update('pks_groups', array('parked' => $f7_mqtt, 'availables' => $f7_total - $f7_mqtt + $f7_renum), array('group_id' => 'F7')); | |||||
| $f7_mqtt_pad = str_pad($f7_total - $f7_mqtt + $f7_renum, 3, '0', STR_PAD_LEFT); | |||||
| $this->vars['mqtt']->publish(MQ_TOPIC_SUBLEVEL, "F7,{$f7_mqtt_pad}", 0); // F7 MQTT | |||||
| */ | |||||
| } | |||||
| } | |||||
| } | |||||
| // 重新計算 | |||||
| public function reculc() | |||||
| { | |||||
| // 找出與與此車位相關的群組 | |||||
| $sql = "select group_id, tot, renum | |||||
| from pks_groups"; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| foreach ($retults as $rows) | |||||
| { | |||||
| // 計算群組異動後的空車位數, 先讀出已停車位數 | |||||
| $sql = "select count(*) as parked from pks where status != 'VA' and pksno in (select pksno from pks_group_member where group_id = '{$rows['group_id']}')"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $group_va = $rows['tot'] + $rows['renum'] - $row_group['parked']; // 群組空車位數 | |||||
| $this->db->update('pks_groups', array('parked' => $row_group['parked'], 'availables' => $group_va), array('group_id' => $rows['group_id'])); | |||||
| // $this->vars['mqtt']->publish("VA-{$rows['group_id']}", "{$group_va}", 0); // 送出剩餘車位數給字幕機 | |||||
| get_headers("http://192.168.51.15/set_num.php?group_id={$rows['group_id']}&num={$group_va}"); | |||||
| echo "group_id:{$rows['group_id']}, tot:{$rows['tot']}, availables:{$group_va}, parked:{$row_group['parked']}, renum:{$rows['renum']}<br />"; | |||||
| } | |||||
| } | |||||
| // 取得所有車位使用狀態 | |||||
| public function query_station_status($station_no) | |||||
| { | |||||
| /* 沒有group_id, pks不能直接用, 要多撈兩張表 | |||||
| $sql = "select pksno, posx, posy, in_time | |||||
| FROM pks | |||||
| WHERE station_no = '".$station_no."' and lpr != ''"; | |||||
| */ | |||||
| $sql = "SELECT pks.pksno AS pksno, pks.posx AS posx, pks.posy AS posy, pks.in_time AS in_time, | |||||
| pks_groups.group_id AS group_id | |||||
| FROM pks | |||||
| LEFT JOIN pks_group_member ON pks.pksno = pks_group_member.pksno AND pks.station_no = pks_group_member.station_no | |||||
| LEFT JOIN pks_groups ON pks_group_member.group_id = pks_groups.group_id | |||||
| WHERE pks.lpr != '' AND pks.station_no = '".$station_no."' AND pks_groups.group_type = '1' "; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| $currentTime = new DateTime("now"); | |||||
| foreach ($retults as $idx => $rows) | |||||
| { | |||||
| $startTime = new DateTime($rows['in_time']); // 進場時間 | |||||
| $interval = $startTime->diff($currentTime); | |||||
| $status = $this->gen_pks_s($interval); // 一般:0, 隔日:1, 超過3日:3, 隔週:7, 隔20日:20 | |||||
| $data['result'][$idx] = array | |||||
| ( | |||||
| 'g'=> $rows['group_id'], | |||||
| 'id'=> $rows['pksno'], | |||||
| 'x' => $rows['posx'], | |||||
| 'y' => $rows['posy'], | |||||
| 's' => $status | |||||
| ); | |||||
| } | |||||
| return $data; | |||||
| } | |||||
| // 取得車位狀態 | |||||
| private function gen_pks_s($interval) | |||||
| { | |||||
| $status = 0; // 一般:0, 隔日:1, 超過3日:3, 隔週:7, 隔20日:20 | |||||
| if($interval->y > 0 || $interval->m > 0 || $interval->d >= 20){ | |||||
| $status = 20; | |||||
| }else if($interval->d >= 7){ | |||||
| $status = 7; | |||||
| }else if($interval->d >= 3){ | |||||
| $status = 3; | |||||
| }else if($interval->d >= 1){ | |||||
| $status = 1; | |||||
| } | |||||
| return $status; | |||||
| } | |||||
| // 取得指定車位使用狀態 | |||||
| public function query_station_pks($station_no, $pksno) | |||||
| { | |||||
| $sql = "SELECT pks.pksno AS pksno, pks.lpr AS lpr, pks.in_time AS in_time, pks.station_no AS station_no, | |||||
| pks_groups.group_id AS group_id, pks_groups.group_name AS group_name, pks_groups.group_type AS type | |||||
| FROM pks | |||||
| LEFT JOIN pks_group_member ON pks.pksno = pks_group_member.pksno AND pks.station_no = pks_group_member.station_no | |||||
| LEFT JOIN pks_groups ON pks_group_member.group_id = pks_groups.group_id | |||||
| WHERE pks.pksno = '".$pksno."' AND pks.station_no = '".$station_no."' AND pks_groups.group_type = '1' "; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| $currentTime = new DateTime("now"); | |||||
| foreach ($retults as $idx => $rows) | |||||
| { | |||||
| $startTime = new DateTime($rows['in_time']); // 進場時間 | |||||
| $interval = $startTime->diff($currentTime); | |||||
| $status = $this->gen_pks_s($interval); // 一般:0, 隔日:1, 超過3日:3, 隔週:7, 隔20日:20 | |||||
| $data['result'][$idx] = array | |||||
| ( | |||||
| 'pksno'=> $rows['pksno'], | |||||
| 'lpr' => $rows['lpr'], | |||||
| 'time' => $rows['in_time'], | |||||
| 'station_no' => $rows['station_no'], | |||||
| 'group_id' => $rows['group_id'], | |||||
| 'group_name' => $rows['group_name'], | |||||
| 'status' => $status | |||||
| ); | |||||
| } | |||||
| return $data; | |||||
| } | |||||
| } | |||||
| <?php | |||||
| /* | |||||
| file: pks_model.php 車位在席資料庫處理模組 | |||||
| */ | |||||
| class Pks_model extends CI_Model | |||||
| { | |||||
| var $vars = array(); | |||||
| function __construct() | |||||
| { | |||||
| parent::__construct(); | |||||
| $this->load->database(); | |||||
| } | |||||
| public function init($vars) | |||||
| { | |||||
| $this->vars = $vars; | |||||
| } | |||||
| // 車輛進出傳入車牌號碼 | |||||
| public function pksio($parms) | |||||
| { | |||||
| switch($parms['io']) | |||||
| { | |||||
| case 'KL': // 車輛入席車辨(lpr)及圖檔 | |||||
| if ($parms['lpr'] == 'NONE') // 在席車辨失敗, 不處理 | |||||
| { | |||||
| trigger_error('在席車辨失敗' . print_r($parms, true)); | |||||
| return false; | |||||
| } | |||||
| // 讀取在席資料(pks) | |||||
| $rows_pks = $this->db | |||||
| ->select('cario_no, lpr, status, confirms') | |||||
| ->from('pks') | |||||
| ->where(array('pksno' => $parms['pksno'], 'station_no' => $parms['sno'])) | |||||
| ->limit(1) | |||||
| ->get() | |||||
| ->row_array(); | |||||
| trigger_error('KL read pks:'.print_r($rows_pks, true)); | |||||
| // 如果已經人工確認或之前已比對有入場資料者, 則重覆再送來的車辨不予理會 | |||||
| if ($rows_pks['confirms'] == 1 || $rows_pks['lpr'] == $parms['lpr']) | |||||
| { | |||||
| trigger_error('KL ignored:'.$rows_pks['lpr']); | |||||
| return false; | |||||
| } | |||||
| /* | |||||
| if ($rows_pks['cario_no'] != 0 || $rows_pks['confirms'] == 1 || $rows_pks['lpr'] == $parms['lpr']) | |||||
| { | |||||
| trigger_error('人工已確認或車號相同不更新pks:'.$rows_pks['lpr']); | |||||
| return false; | |||||
| } | |||||
| */ | |||||
| // 讀取進場時間, 如讀不到資料, 以目前時間取代(add by TZUSS 2016-02-23) | |||||
| $rows_cario = $this->db | |||||
| ->select('cario_no, in_time') | |||||
| ->from('cario') | |||||
| ->where(array('in_out' => 'CI', 'obj_id' => $parms['lpr'], 'finished' => 0, 'err' => 0, 'station_no' => $parms['sno'])) | |||||
| ->order_by('cario_no', 'desc') | |||||
| ->limit(1) | |||||
| ->get() | |||||
| ->row_array(); | |||||
| if (!empty($rows_cario['cario_no'])) // 有入場資料 | |||||
| { | |||||
| $cario_no = $rows_cario['cario_no']; // 入場序號 | |||||
| $in_time = $rows_cario['in_time']; | |||||
| // 在席與入場資料相符, 分別在cario與pks記錄之 | |||||
| $data_cario = array | |||||
| ( | |||||
| 'pksno' => $parms['pksno'], | |||||
| 'pks_time' => date('Y-m-d H:i:s') | |||||
| ); | |||||
| $this->db->update('cario', $data_cario, array('cario_no' => $cario_no, 'station_no' => $parms['sno'])); | |||||
| } | |||||
| else // 查無入場資料, 即時通知 | |||||
| { | |||||
| $cario_no = 0; | |||||
| $in_time = date('Y-m-d H:i:s'); | |||||
| /* | |||||
| $jdata = json_encode(array | |||||
| ( | |||||
| 'pksno' => $parms['pksno'], | |||||
| 'lpr' => $parms['lpr'], | |||||
| 'in_time' => $in_time | |||||
| ,'pic_name' => $parms['pic_name'] | |||||
| ), JSON_UNESCAPED_UNICODE); | |||||
| */ | |||||
| // $this->vars['mqtt']-lish('PKS_WITHOUT_IN', "{$jdata}", 0); // 待web完成 ??? | |||||
| trigger_error('在席無進場資料:'. print_r($parms, true)); | |||||
| } | |||||
| // 車入格後的車牌辨識(lpr), 傅送圖檔 | |||||
| array_map('unlink', glob(PKS_PIC."pks-{$parms['pksno']}-*.jpg")); // 刪除舊照片 | |||||
| $config['upload_path'] = PKS_PIC; | |||||
| $config['allowed_types'] = 'gif|jpg|png'; | |||||
| // ex. pks-2016-1625AB-1-2015080526.jpg -> pks-車位編號-車號-設備編號-時間.jpg | |||||
| $config['file_name'] = "pks-{$parms['pksno']}-{$parms['lpr']}-{$parms['ivsno']}-{$this->vars['time_num']}.jpg"; | |||||
| $this->load->library('upload', $config); | |||||
| $parms['pic_name'] = $config['file_name']; | |||||
| if($this->upload->do_upload('cars')) | |||||
| { | |||||
| // 若無錯誤,則上傳檔案 | |||||
| $file = $this->upload->data('cars'); | |||||
| } | |||||
| else | |||||
| { | |||||
| trigger_error('入席傳檔錯誤:'. print_r($parms, true)); | |||||
| } | |||||
| $data = array | |||||
| ( | |||||
| 'cario_no' => $cario_no, | |||||
| 'lpr' => $parms['lpr'], | |||||
| 'status' => 'LR', // 車格佔用並有車號 | |||||
| 'confirms' => 0, // 預設人工未確認 | |||||
| 'pic_name' => $parms['pic_name'], | |||||
| 'in_time' => $in_time | |||||
| ); | |||||
| // 車號及照片檔名填入資料庫內 | |||||
| $this->db->update('pks', $data, array('pksno' => $parms['pksno'], 'station_no' => $parms['sno'])); | |||||
| break; | |||||
| case 'KI': // 車輛入席, 各區空車位與佔位各加減1 | |||||
| $rows = $this->db->select('status') | |||||
| ->from('pks') | |||||
| ->where(array('pksno' => $parms['pksno'], 'station_no' => $parms['sno'])) | |||||
| ->get() | |||||
| ->row_array(); | |||||
| // if (!empty($rows['status']) && $rows['status'] == 'LR') break; // 仍有車在席, 不應再有KI, ignore | |||||
| if (!empty($rows['status']) && $rows['status'] == 'LR') return true; // 仍有車在席, 不應再有KI, ignore | |||||
| $data = array | |||||
| ( | |||||
| 'cario_no' => 0, | |||||
| 'lpr' => '', | |||||
| 'status' => 'OC', // 車格佔用但尚無車號 | |||||
| 'confirms' => 0, | |||||
| 'pic_name' => '', | |||||
| 'in_time' => null | |||||
| ); | |||||
| $this->db->update('pks', $data, array('pksno' => $parms['pksno'], 'station_no' => $parms['sno'])); | |||||
| break; | |||||
| case 'KO': // 車輛離席, 各區空車位與佔位各加減1 | |||||
| $data = array | |||||
| ( | |||||
| 'cario_no' => 0, | |||||
| 'lpr' => '', | |||||
| 'status' => 'VA', // 車格佔用但尚無車號 | |||||
| 'confirms' => 0, | |||||
| 'pic_name' => '', | |||||
| 'in_time' => null | |||||
| ); | |||||
| $this->db->update('pks', $data, array('pksno' => $parms['pksno'], 'station_no' => $parms['sno'])); | |||||
| break; | |||||
| } | |||||
| /* | |||||
| // 找出與與此車位相關的群組 | |||||
| $sql = "select group_id, tot, renum | |||||
| from pks_groups | |||||
| where group_id in | |||||
| (select group_id from pks_group_member where station_no = {$this->vars['station_no']} and pksno = {$parms['pksno']})"; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| foreach ($retults as $rows) | |||||
| { | |||||
| // 計算群組異動後的空車位數, 先讀出已停車位數 | |||||
| $sql = "select count(*) as parked from pks where status != 'VA' and pksno in (select pksno from pks_group_member where group_id = '{$rows['group_id']}')"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $group_va = $rows['tot'] + $rows['renum'] - $row_group['parked']; // 群組空車位數 | |||||
| $this->db->update('pks_groups', array('parked' => $row_group['parked'], 'availables' => $group_va), array('group_id' => $rows['group_id'])); | |||||
| get_headers("http://192.168.51.15/set_num.php?group_id={$rows['group_id']}&num={$group_va}"); | |||||
| // $this->vars['mqtt']->publish("VA-{$rows['group_id']}", "{$group_va}", 0); // 送出剩餘車位數給字幕機 | |||||
| // 總車位數暫無需處理 | |||||
| } | |||||
| */ | |||||
| // 找出與與此車位相關的群組 | |||||
| $sql = "select group_id, tot, renum, availables | |||||
| from pks_groups | |||||
| where group_id in | |||||
| (select group_id from pks_group_member where station_no = {$parms['sno']} and pksno = {$parms['pksno']})"; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| foreach ($retults as $rows) | |||||
| { | |||||
| // 計算群組異動後的空車位數, 先讀出已停車位數 | |||||
| $sql = "select count(*) as parked from pks where status != 'VA' and pksno in (select pksno from pks_group_member where group_id = '{$rows['group_id']}')"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $group_va = $rows['tot'] + $rows['renum'] - $row_group['parked']; // 群組空車位數 | |||||
| // 有變動才處理更新 | |||||
| if($rows['availables'] != $group_va) | |||||
| { | |||||
| // 防止負值 | |||||
| if($group_va < 0){ | |||||
| $group_va = 0; | |||||
| } | |||||
| $group_va_pad = str_pad($group_va, 3, '0', STR_PAD_LEFT); // 補零 | |||||
| $this->db->update('pks_groups', array('parked' => $row_group['parked'], 'availables' => $group_va), array('group_id' => $rows['group_id'])); | |||||
| $this->vars['mqtt']->publish(MQ_TOPIC_SUBLEVEL, "{$rows['group_id']},{$group_va_pad}", 0); // 送出剩餘車位數給字幕機 | |||||
| // 總車位數暫無需處理 | |||||
| // 七樓無在席, 手動或用猜的 | |||||
| /* | |||||
| $f7_total = 74; | |||||
| $sql = "select renum from pks_groups where group_id = 'F7'"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $f7_renum = $row_group['renum']; | |||||
| $total_parked_sql = "select count(cario_no) as parked | |||||
| from cario where | |||||
| cario.in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY) | |||||
| and cario.finished = 0 | |||||
| and cario.err = 0 | |||||
| and cario.in_out = 'CI' | |||||
| and cario.out_time is null"; | |||||
| $total_parked_row_group = $this->db->query($total_parked_sql)->row_array(); | |||||
| $sql = "select count(pksno) as parked from pks where status != 'VA'"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $f7_mqtt = $total_parked_row_group['parked'] - $row_group['parked']; | |||||
| if($f7_mqtt > $f7_total){ | |||||
| $f7_mqtt = $f7_total; | |||||
| }else if($f7_mqtt <= 0){ | |||||
| $f7_mqtt = 0; | |||||
| } | |||||
| $this->db->update('pks_groups', array('parked' => $f7_mqtt, 'availables' => $f7_total - $f7_mqtt + $f7_renum), array('group_id' => 'F7')); | |||||
| $f7_mqtt_pad = str_pad($f7_total - $f7_mqtt + $f7_renum, 3, '0', STR_PAD_LEFT); | |||||
| $this->vars['mqtt']->publish(MQ_TOPIC_SUBLEVEL, "F7,{$f7_mqtt_pad}", 0); // F7 MQTT | |||||
| */ | |||||
| } | |||||
| } | |||||
| } | |||||
| // 重新計算 | |||||
| public function reculc() | |||||
| { | |||||
| // 找出與與此車位相關的群組 | |||||
| $sql = "select group_id, tot, renum | |||||
| from pks_groups"; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| foreach ($retults as $rows) | |||||
| { | |||||
| // 計算群組異動後的空車位數, 先讀出已停車位數 | |||||
| $sql = "select count(*) as parked from pks where status != 'VA' and pksno in (select pksno from pks_group_member where group_id = '{$rows['group_id']}')"; | |||||
| $row_group = $this->db->query($sql)->row_array(); | |||||
| $group_va = $rows['tot'] + $rows['renum'] - $row_group['parked']; // 群組空車位數 | |||||
| $this->db->update('pks_groups', array('parked' => $row_group['parked'], 'availables' => $group_va), array('group_id' => $rows['group_id'])); | |||||
| // $this->vars['mqtt']->publish("VA-{$rows['group_id']}", "{$group_va}", 0); // 送出剩餘車位數給字幕機 | |||||
| get_headers("http://192.168.51.15/set_num.php?group_id={$rows['group_id']}&num={$group_va}"); | |||||
| echo "group_id:{$rows['group_id']}, tot:{$rows['tot']}, availables:{$group_va}, parked:{$row_group['parked']}, renum:{$rows['renum']}<br />"; | |||||
| } | |||||
| } | |||||
| // 取得所有車位使用狀態 | |||||
| public function query_station_status($station_no) | |||||
| { | |||||
| /* 沒有group_id, pks不能直接用, 要多撈兩張表 | |||||
| $sql = "select pksno, posx, posy, in_time | |||||
| FROM pks | |||||
| WHERE station_no = '".$station_no."' and lpr != ''"; | |||||
| */ | |||||
| $sql = "SELECT pks.pksno AS pksno, pks.posx AS posx, pks.posy AS posy, pks.in_time AS in_time, | |||||
| pks_groups.group_id AS group_id | |||||
| FROM pks | |||||
| LEFT JOIN pks_group_member ON pks.pksno = pks_group_member.pksno AND pks.station_no = pks_group_member.station_no | |||||
| LEFT JOIN pks_groups ON pks_group_member.group_id = pks_groups.group_id | |||||
| WHERE pks.lpr != '' AND pks.station_no = '".$station_no."' AND pks_groups.group_type = '1' "; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| $currentTime = new DateTime("now"); | |||||
| foreach ($retults as $idx => $rows) | |||||
| { | |||||
| $startTime = new DateTime($rows['in_time']); // 進場時間 | |||||
| $interval = $startTime->diff($currentTime); | |||||
| $status = $this->gen_pks_s($interval); // 一般:0, 隔日:1, 超過3日:3, 隔週:7, 隔20日:20 | |||||
| $data['result'][$idx] = array | |||||
| ( | |||||
| 'g'=> $rows['group_id'], | |||||
| 'id'=> $rows['pksno'], | |||||
| 'x' => $rows['posx'], | |||||
| 'y' => $rows['posy'], | |||||
| 's' => $status | |||||
| ); | |||||
| } | |||||
| return $data; | |||||
| } | |||||
| // 取得車位狀態 | |||||
| private function gen_pks_s($interval) | |||||
| { | |||||
| $status = 0; // 一般:0, 隔日:1, 超過3日:3, 隔週:7, 隔20日:20 | |||||
| if($interval->y > 0 || $interval->m > 0 || $interval->d >= 20){ | |||||
| $status = 20; | |||||
| }else if($interval->d >= 7){ | |||||
| $status = 7; | |||||
| }else if($interval->d >= 3){ | |||||
| $status = 3; | |||||
| }else if($interval->d >= 1){ | |||||
| $status = 1; | |||||
| } | |||||
| return $status; | |||||
| } | |||||
| // 取得指定車位使用狀態 | |||||
| public function query_station_pks($station_no, $pksno) | |||||
| { | |||||
| $sql = "SELECT pks.pksno AS pksno, pks.lpr AS lpr, pks.in_time AS in_time, pks.station_no AS station_no, | |||||
| pks_groups.group_id AS group_id, pks_groups.group_name AS group_name, pks_groups.group_type AS type | |||||
| FROM pks | |||||
| LEFT JOIN pks_group_member ON pks.pksno = pks_group_member.pksno AND pks.station_no = pks_group_member.station_no | |||||
| LEFT JOIN pks_groups ON pks_group_member.group_id = pks_groups.group_id | |||||
| WHERE pks.pksno = '".$pksno."' AND pks.station_no = '".$station_no."' AND pks_groups.group_type = '1' "; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| $currentTime = new DateTime("now"); | |||||
| foreach ($retults as $idx => $rows) | |||||
| { | |||||
| $startTime = new DateTime($rows['in_time']); // 進場時間 | |||||
| $interval = $startTime->diff($currentTime); | |||||
| $status = $this->gen_pks_s($interval); // 一般:0, 隔日:1, 超過3日:3, 隔週:7, 隔20日:20 | |||||
| $data['result'][$idx] = array | |||||
| ( | |||||
| 'pksno'=> $rows['pksno'], | |||||
| 'lpr' => $rows['lpr'], | |||||
| 'time' => $rows['in_time'], | |||||
| 'station_no' => $rows['station_no'], | |||||
| 'group_id' => $rows['group_id'], | |||||
| 'group_name' => $rows['group_name'], | |||||
| 'status' => $status | |||||
| ); | |||||
| } | |||||
| return $data; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,144 @@ | |||||
| <?php | |||||
| /* | |||||
| file: Qcar2_model.php 查車2 | |||||
| */ | |||||
| class Qcar2_model extends CI_Model | |||||
| { | |||||
| function __construct() | |||||
| { | |||||
| parent::__construct(); | |||||
| $this->load->database(); | |||||
| } | |||||
| // 查車 | |||||
| public function q_pks($lpr) | |||||
| { | |||||
| $sql = "select p.pksno, p.pic_name, p.update_time, p.in_time, p.posx, p.posy, m.group_id, g.group_name, g.floors | |||||
| from pks p, pks_group_member m, pks_groups g | |||||
| where p.pksno = m.pksno | |||||
| and m.group_id = g.group_id | |||||
| and g.group_type = 1 | |||||
| and p.lpr = '{$lpr}' | |||||
| limit 1"; | |||||
| $rows = $this->db->query($sql)->row_array(); | |||||
| //if (!empty($rows['pic_name'])) $rows['pic_name'] = str_replace('.jpg', '', $rows['pic_name']); | |||||
| //else $rows['pksno'] = 0; // 如無該筆資料, 車位號碼設為0 | |||||
| return $rows; | |||||
| } | |||||
| // 模糊比對 | |||||
| function getLevenshteinSQLStatement($word, $target) | |||||
| { | |||||
| $words = array(); | |||||
| if(strlen($word) >= 5) | |||||
| { | |||||
| for ($i = 0; $i < strlen($word); $i++) { | |||||
| // insertions | |||||
| $words[] = substr($word, 0, $i) . '_' . substr($word, $i); | |||||
| // deletions | |||||
| $words[] = substr($word, 0, $i) . substr($word, $i + 1); | |||||
| // substitutions | |||||
| //$words[] = substr($word, 0, $i) . '_' . substr($word, $i + 1); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| for ($i = 0; $i < strlen($word); $i++) { | |||||
| // insertions | |||||
| $words[] = substr($word, 0, $i) . '_' . substr($word, $i); | |||||
| } | |||||
| } | |||||
| // last insertion | |||||
| $words[] = $word . '_'; | |||||
| //return $words; | |||||
| $fuzzy_statement = ' ('; | |||||
| foreach ($words as $idx => $word) | |||||
| { | |||||
| $fuzzy_statement .= " {$target} LIKE '%{$word}%' OR "; | |||||
| } | |||||
| $last_or_pos = strrpos($fuzzy_statement, 'OR'); | |||||
| if($last_or_pos !== false) | |||||
| { | |||||
| $fuzzy_statement = substr_replace($fuzzy_statement, ')', $last_or_pos, strlen('OR')); | |||||
| } | |||||
| return $fuzzy_statement; | |||||
| } | |||||
| // 取得進場資訊 (模糊比對) | |||||
| public function q_fuzzy_pks($word) | |||||
| { | |||||
| if(empty($word) || strlen($word) <= 0 || strlen($word) > 10) | |||||
| { | |||||
| return null; | |||||
| } | |||||
| $sql = "SELECT station_no, lpr, in_time, pic_name as pks_pic_name | |||||
| FROM pks | |||||
| WHERE {$this->getLevenshteinSQLStatement($word, 'lpr')} | |||||
| ORDER BY lpr ASC"; | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| if(count($retults) > 0) | |||||
| { | |||||
| foreach ($retults as $idx => $rows) | |||||
| { | |||||
| $pks_pic_path = ''; | |||||
| if(!empty($rows['pks_pic_name'])) | |||||
| { | |||||
| //$pks_pic_path = APP_URL.'pks_pics/'.str_replace('.jpg', '', $rows['pks_pic_name']); | |||||
| $pks_pic_path = SERVER_URL.'pkspic/'.$rows['pks_pic_name']; | |||||
| } | |||||
| $data['result'][$idx] = array | |||||
| ( | |||||
| 'lpr'=> $rows['lpr'], | |||||
| 'pks_pic_path' => $pks_pic_path, | |||||
| 'station_no' => $rows['station_no'], | |||||
| 'in_time' => $rows['in_time'] | |||||
| ); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| // 讀取入場資料 | |||||
| $sql = "SELECT cario.station_no as station_no, cario.obj_id as lpr, cario.in_time as in_time, cario.in_pic_name as pks_pic_name | |||||
| FROM cario | |||||
| WHERE {$this->getLevenshteinSQLStatement($word, 'obj_id')} | |||||
| AND in_out = 'CI' AND finished = 0 AND err = 0 AND out_time IS NULL | |||||
| ORDER BY lpr ASC"; | |||||
| // AND in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY) | |||||
| $retults = $this->db->query($sql)->result_array(); | |||||
| if(count($retults) > 0) | |||||
| { | |||||
| foreach ($retults as $idx => $rows) | |||||
| { | |||||
| $pks_pic_path = ''; | |||||
| if(!empty($rows['pks_pic_name'])) | |||||
| { | |||||
| $pic_name = str_replace('.jpg', '', $rows['pks_pic_name']); | |||||
| $arr = explode('-', $pic_name); | |||||
| $pks_pic_path = SERVER_URL.'carspic/'.substr($arr[7], 0, 8).'/'.$pic_name.'.jpg'; | |||||
| } | |||||
| $data['result'][$idx] = array | |||||
| ( | |||||
| 'lpr'=> $rows['lpr'], | |||||
| 'pks_pic_path' => $pks_pic_path, | |||||
| 'station_no' => $rows['station_no'], | |||||
| 'in_time' => $rows['in_time'] | |||||
| ); | |||||
| } | |||||
| } | |||||
| } | |||||
| return $data; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,454 @@ | |||||
| <!DOCTYPE html> | |||||
| <html lang="zh-TW"> | |||||
| <head> | |||||
| <meta charset="utf-8"> | |||||
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
| <meta name="description" content=""> | |||||
| <meta name="author" content=""> | |||||
| <title>歐特儀自動化服務機</title> | |||||
| <!-- Bootstrap Core CSS --> | |||||
| <link href="<?=BOOTSTRAPS?>bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> | |||||
| <!-- MetisMenu CSS --> | |||||
| <link href="<?=BOOTSTRAPS?>bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet"> | |||||
| <!-- Timeline CSS --> | |||||
| <link href="<?=BOOTSTRAPS?>dist/css/timeline.css" rel="stylesheet"> | |||||
| <!-- Custom CSS --> | |||||
| <link href="<?=BOOTSTRAPS?>dist/css/sb-admin-3.css" rel="stylesheet"> | |||||
| <!-- Morris Charts CSS --> | |||||
| <link href="<?=BOOTSTRAPS?>bower_components/morrisjs/morris.css" rel="stylesheet"> | |||||
| <!-- Custom Fonts --> | |||||
| <link href="<?=BOOTSTRAPS?>bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"> | |||||
| </head> | |||||
| <body style="font-family:Microsoft JhengHei;"> | |||||
| <div id="wrapper"> | |||||
| <div id="page-wrapper"><?php /* 主要資料顯示區 */ ?> | |||||
| <div class="row"> | |||||
| <div class="col-lg-12"> | |||||
| <h1 class="page-header">歐特儀自動化服務機</h1><?php /* 右側小表頭 */ ?> | |||||
| </div> | |||||
| <!-- /.col-lg-12 --> | |||||
| </div> | |||||
| <!-- /.row --> | |||||
| <?php /* ----- 查車作業 ----- */ ?> | |||||
| <div data-items="input_lpr" class="row"> | |||||
| <div class="col-lg-12"> | |||||
| <div class="panel panel-default"> | |||||
| <div class="panel-heading" style="font-size:28px;"><?php /* 資料顯示區灰色小表頭 */ ?> | |||||
| 車位查詢 | |||||
| </div> | |||||
| <div class="panel-body"> | |||||
| <div data-rows class="row" style="font-size:28px;"> | |||||
| <div class="col-lg-8"> | |||||
| <form id="fuzzy_search_lpr" role="form" method="post"> | |||||
| <div class="form-group"> | |||||
| <input type="text" id="fuzzy_input" name="fuzzy_input" class="form-control" style="text-transform:uppercase;height:64px;font-size:32px" | |||||
| placeholder="請輸入車牌關鍵字 ( 3 到 7 碼 ex. 111)" | |||||
| autofocus required pattern="[A-Za-z0-9]*" | |||||
| data-validation="length" | |||||
| data-validation-length="3-7" | |||||
| data-validation-error-msg="請輸入車牌關鍵字 ( 3 到 7 碼 ex. 111)"> | |||||
| </div> | |||||
| | |||||
| <button type="reset" class="btn btn-default" style="font-size:28px;" onclick="$('#fuzzy_search_lpr_msg').text('');">清除</button> | |||||
| | |||||
| <span id='fuzzy_search_lpr_msg' style="font-size:28px;color:red;"></span> | |||||
| | |||||
| <button type="submit" class="btn btn-large btn-success pull-right" style="font-size:28px;">搜尋車牌</button> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| <br/> | |||||
| <div id="carin_query_list" class="col-lg-12 dataTable_wrapper" style="display:none; font-size:28px;"> | |||||
| <table id="lpr_query_list" class="table table-striped table-bordered table-hover"> | |||||
| <thead> | |||||
| <tr> | |||||
| <th style="text-align:center;">車號</th> | |||||
| <th style="text-align:center;">進場時間</th> | |||||
| <th style="text-align:center;">在席照片</th> | |||||
| <th style="text-align:center;">功能</th> | |||||
| </tr> | |||||
| </thead> | |||||
| <tbody id="carin_query_tbody" style="font-size:28px;"></tbody> | |||||
| </table> | |||||
| </div><?php /* ----- end of dataTable_wrapper ----- */?> | |||||
| </div> | |||||
| <!-- /.panel-body --> | |||||
| </div> | |||||
| <!-- /.panel --> | |||||
| </div> | |||||
| <!-- /.col-lg-12 --> | |||||
| </div> | |||||
| <?php /* ----- 查詢作業(結束) ----- */ ?> | |||||
| <?php /* ----- 查詢結果 ----- */ ?> | |||||
| <!-- div data-items="rent_sync" class="row" style="display:none;"--> | |||||
| <div data-items="output_pks" class="row" style="display:none;"> | |||||
| <div class="col-lg-6"> | |||||
| <div class="panel panel-default"> | |||||
| <div class="panel-heading" style="font-size:28px;"><?php /* 資料顯示區灰色小表頭 */ ?> | |||||
| 查車結果 | |||||
| </div> | |||||
| <div class="panel-body" style="margin: 0px auto;"> | |||||
| <div data-rows class="row"> | |||||
| <div class="col-lg-12" style="margin: 0px auto;"> | |||||
| <table class="table table-striped table-bordered table-hover""> | |||||
| <tbody style="font-size:28px;"> | |||||
| <tr> | |||||
| <td style="text-align:right;vertical-align: middle;">車號</td> | |||||
| <td id="show_lpr" style="text-align:left;vertical-align: middle;"></td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td style="text-align:right;vertical-align: middle;">所在樓層</td> | |||||
| <td id="show_floors" style="text-align:left;vertical-align: middle; font-size:28px; color:blue;"></td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td style="text-align:right;vertical-align: middle;">停入時間</td> | |||||
| <td id="show_update_time" style="text-align:left;vertical-align: middle;"></td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td colspan="2" style="text-align:center;vertical-align: middle;"> | |||||
| <button type="button" class="btn btn-large btn-success pull-right" style="font-size:28px;" onclick="show_item('input_lpr');">結束查詢</button> | |||||
| </td> | |||||
| </tr> | |||||
| </tbody> | |||||
| </table> | |||||
| </div> | |||||
| <!-- /.col-lg-6 (nested) --> | |||||
| </div> | |||||
| <!-- /.row (nested) --> | |||||
| </div> | |||||
| <!-- /.panel-body --> | |||||
| </div> | |||||
| <!-- /.panel --> | |||||
| </div> | |||||
| <div class="col-lg-6"> | |||||
| <div class="panel panel-default"> | |||||
| <div class="panel-heading" style="font-size:28px;"> | |||||
| 在席照片 | |||||
| </div> | |||||
| </div> | |||||
| <div class="panel-body" style="margin: 0px auto;"> | |||||
| <div class="col-lg-12" style="margin: 0px auto;"> | |||||
| <table class="table table-striped table-bordered table-hover""> | |||||
| <tbody> | |||||
| <tr> | |||||
| <td colspan="2" style="text-align:center;vertical-align: middle;"> | |||||
| <img id="show_img" height="280" width="400" /> | |||||
| </td> | |||||
| </tr> | |||||
| </tbody> | |||||
| </table> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <!-- /.col-lg-12 --> | |||||
| </div> | |||||
| <!-- /#page-wrapper --> | |||||
| </div> | |||||
| <!-- /#wrapper --> | |||||
| <!-- jQuery --> | |||||
| <script src="<?=BOOTSTRAPS?>bower_components/jquery/dist/jquery.min.js"></script> | |||||
| <!-- Bootstrap Core JavaScript --> | |||||
| <script src="<?=BOOTSTRAPS?>bower_components/bootstrap/dist/js/bootstrap.min.js"></script> | |||||
| <!-- Metis Menu Plugin JavaScript --> | |||||
| <script src="<?=BOOTSTRAPS?>bower_components/metisMenu/dist/metisMenu.min.js"></script> | |||||
| <!-- Morris Charts JavaScript --> | |||||
| <script src="<?=BOOTSTRAPS?>bower_components/raphael/raphael-min.js"></script> | |||||
| <!--script src="<?=BOOTSTRAPS?>bower_components/morrisjs/morris.min.js"></script--> | |||||
| <!--script src="<?=BOOTSTRAPS?>js/morris-data.js"></script--> | |||||
| <!-- virtual keyboard --> | |||||
| <link href="<?=WEB_LIB?>virtual-keyboard/css/jquery-ui.min.css" rel="stylesheet"> | |||||
| <link href="<?=WEB_LIB?>virtual-keyboard/css/keyboard.css" rel="stylesheet"> | |||||
| <script src="<?=WEB_LIB?>virtual-keyboard/js/jquery-ui.min.js"></script> | |||||
| <script src="<?=WEB_LIB?>virtual-keyboard/js/jquery.keyboard.js"></script> | |||||
| <script src="<?=WEB_LIB?>virtual-keyboard/js/jquery.keyboard.extension-caret.js"></script> | |||||
| <!-- alertify --> | |||||
| <link href="<?=WEB_LIB?>css/alertify.core.css" rel="stylesheet"> | |||||
| <link href="<?=WEB_LIB?>css/alertify.bootstrap.css" rel="stylesheet"> | |||||
| <script src="<?=WEB_LIB?>js/alertify.min.js"></script> | |||||
| <!-- moment --> | |||||
| <script src="<?=WEB_LIB?>js/moment.min.js"></script> | |||||
| <!-- jQuery validate --> | |||||
| <script src="<?=WEB_LIB?>form-validator/jquery.form-validator.min.js"></script> | |||||
| <!-- Custom Theme JavaScript --> | |||||
| <script src="<?=BOOTSTRAPS?>dist/js/sb-admin-2.js"></script> | |||||
| <div id="works" style="display:none;"></div><?php /* 作為浮動顯示區之用 */ ?> | |||||
| </body> | |||||
| </html> | |||||
| <script> | |||||
| <?php /* alertify function */ ?> | |||||
| function alertify_count_down($msg, $delay) | |||||
| { | |||||
| alertify.set({delay : $delay}); | |||||
| alertify.log($msg); | |||||
| } | |||||
| function alertify_log($msg) | |||||
| { | |||||
| alertify.set({delay : 2000}); | |||||
| alertify.log($msg); | |||||
| } | |||||
| function alertify_error($msg) | |||||
| { | |||||
| alertify.set({delay : 2000}); | |||||
| alertify.error($msg); | |||||
| } | |||||
| function alertify_success($msg) | |||||
| { | |||||
| alertify.set({delay : 2000}); | |||||
| alertify.success($msg); | |||||
| } | |||||
| function alertify_msg($msg) | |||||
| { | |||||
| alertify.set({ labels: { | |||||
| ok : "確定" | |||||
| } }); | |||||
| alertify.alert($msg, function (e){ | |||||
| // do nothing | |||||
| }); | |||||
| } | |||||
| function reset_query() | |||||
| { | |||||
| $("#fuzzy_input").val(""); | |||||
| $("#carin_query_list").hide(); | |||||
| return false; | |||||
| } | |||||
| var refreshIntervalId = 0; // timer id | |||||
| <?php /* 顯示指定項目 */ ?> | |||||
| function show_item(tags) | |||||
| { | |||||
| // 查車 | |||||
| reset_query(); | |||||
| // 付款 | |||||
| $("#payment_lpr").val("");<?php /* 清除車號欄位 */ ?> | |||||
| $("#show_member_name").val(""); | |||||
| $("#show_payment_lpr").val(""); | |||||
| $("#show_end_date").val(""); | |||||
| $("#show_next_start").val(""); | |||||
| $("#show_next_end").val(""); | |||||
| $("#show_amt").val(""); | |||||
| $("#invoice_receiver").val(""); | |||||
| $("#company_no").val(""); | |||||
| $("#email").val(""); | |||||
| $("#mobile").val(""); | |||||
| $("#show_order_no").val(""); | |||||
| $("#show_amt_detail").val(""); | |||||
| $("#show_balance_time_limit_countdown").val(""); | |||||
| if(tags.indexOf('payment_data') < 0 && tags.indexOf('price_data') < 0){ | |||||
| clearInterval(refreshIntervalId); // 消除倒數計時timer | |||||
| } | |||||
| $("[data-items]").hide(); | |||||
| $("[data-items="+tags+"]").show(); | |||||
| return false; | |||||
| } | |||||
| <?php /* 顯示指定項目, 不修改資料 */ ?> | |||||
| function show_item_without_change(tags) | |||||
| { | |||||
| $("[data-items]").hide(); | |||||
| $("[data-items="+tags+"]").show(); | |||||
| return false; | |||||
| } | |||||
| // 查車牌 | |||||
| function check_lpr(idx) | |||||
| { | |||||
| $.ajax | |||||
| ({ | |||||
| url: "<?=APP_URL?>q_pks", | |||||
| dataType:"json", | |||||
| type:"post", | |||||
| data:{ "lpr" : $("#lpr_"+idx).text() }, | |||||
| success:function(jdata) | |||||
| { | |||||
| if(!jdata) | |||||
| { | |||||
| //alertify_msg("您的愛車可能在頂樓! 謝謝"); | |||||
| alertify_msg("找不到。。謝謝"); | |||||
| return false; | |||||
| } | |||||
| else if (jdata["pksno"] == "0") | |||||
| { | |||||
| alertify_msg("查無資料,請鍵入正確資料"); | |||||
| return false; | |||||
| } | |||||
| $("#show_lpr").text($("#lpr_"+idx).text()); | |||||
| //$("#show_floors").html(jdata["group_name"]+"<br/> ( 車格: " + jdata["pksno"].charAt(0) + "-" + jdata["pksno"].substr(2) +" )"); | |||||
| //$("#show_floors").html(jdata["group_name"]+"<br/> ( 車格: " + jdata["pksno"] +" )"); | |||||
| $("#show_floors").html(jdata["group_name"]+"<br/> ( 車格: " + jdata["pksno"].substr(-3, 3) +" )"); | |||||
| $("#show_update_time").text(jdata["in_time"]); | |||||
| $("#show_img").attr("src", "<?=SERVER_URL?>pkspic/"+jdata["pic_name"]); | |||||
| show_item("output_pks"); | |||||
| // 顯示位置圖 | |||||
| if (jdata["group_id"]){ | |||||
| //var groupSplit = jdata["group_id"].split('-'); // ex. B3-3 | |||||
| //var floor = groupSplit[0]; | |||||
| var floor = jdata["floors"]; | |||||
| var x = jdata["posx"]; | |||||
| var y = jdata["posy"]; | |||||
| // 畫出指定位置 | |||||
| AltobObject.AtsMap.drawPosition(floor, x, y); | |||||
| // show map | |||||
| $("[data-items="+floor+"]").show(); | |||||
| } | |||||
| } | |||||
| }); | |||||
| return false; | |||||
| } | |||||
| $(document).ready(function() | |||||
| { | |||||
| <?php /* 鎖右鍵 */ ?> | |||||
| $(document).bind('contextmenu', function (e) { | |||||
| e.preventDefault(); | |||||
| }); | |||||
| <?php /* 車牌模糊搜尋 */ ?> | |||||
| $("#fuzzy_search_lpr").submit(function(event) | |||||
| { | |||||
| event.preventDefault(); | |||||
| // 清除搜尋提示訊息 | |||||
| $("#fuzzy_search_lpr_msg").text(''); | |||||
| if(! $("#fuzzy_search_lpr").isValid()) return false; | |||||
| $.ajax | |||||
| ({ | |||||
| url: "<?=APP_URL?>q_fuzzy_pks", | |||||
| type: "post", | |||||
| dataType:"json", | |||||
| data: $(this).serialize(), | |||||
| success: function(jdata) | |||||
| { | |||||
| if (!jdata) | |||||
| { | |||||
| //alert("查無此車 !"); | |||||
| $("#fuzzy_search_lpr_msg").text('查無此車'); | |||||
| return false; | |||||
| } | |||||
| // 清除搜尋提示訊息 | |||||
| $("#fuzzy_search_lpr_msg").text(''); | |||||
| var tmp_str_array = []; | |||||
| for(idx in jdata.result) | |||||
| { | |||||
| tmp_str_array = tmp_str_array.concat( | |||||
| [ | |||||
| "<tr><td id='lpr_", idx, "' style='text-align:center;vertical-align:middle;'>", jdata.result[idx]['lpr'] , | |||||
| "</td><td id='in_time_", idx, "'style='text-align:center;vertical-align:middle;'>", jdata.result[idx]['in_time'], | |||||
| "</td><td id='pks_pic_path_", idx, "'style='text-align:center;vertical-align:middle;'><img height='57' width='150' src='", jdata.result[idx]['pks_pic_path'], "' />", | |||||
| "</td><td style='text-align:center;vertical-align:middle;'><button class='btn btn-large btn-success' style='font-size:28px;' onclick='check_lpr(", idx, ");'>查詢</button>" , | |||||
| "</td></tr>" | |||||
| ]); | |||||
| } | |||||
| $("#carin_query_tbody").html(tmp_str_array.join('')); | |||||
| $("#carin_query_list").show(); | |||||
| } | |||||
| }); | |||||
| }); | |||||
| // Custom: altob-input | |||||
| // ******************** | |||||
| $('#fuzzy_input').keyboard({ | |||||
| css : { | |||||
| // input & preview styles | |||||
| input : 'ui-widget-content ui-corner-all', | |||||
| // keyboard container - this wraps the preview area (if `usePreview` is true) and all keys | |||||
| container : 'ui-widget-content ui-widget ui-corner-all ui-helper-clearfix', | |||||
| // default keyboard button state, these are applied to all keys, the remaining css options are toggled as needed | |||||
| buttonDefault : 'ui-state-default ui-corner-all', | |||||
| // hovered button | |||||
| buttonHover : 'ui-state-hover', | |||||
| // Action keys (e.g. Accept, Cancel, Tab, etc); this replaces the "actionClass" option | |||||
| buttonAction : 'ui-state-active', | |||||
| // used when disabling the decimal button {dec} when a decimal exists in the input area | |||||
| buttonDisabled : 'ui-state-disabled' | |||||
| }, | |||||
| display: { | |||||
| 'bksp' : '\u2190', | |||||
| 'default' : 'ABC', | |||||
| 'accept' : '確 認' | |||||
| }, | |||||
| layout: 'custom', | |||||
| customLayout: { | |||||
| 'default': [ | |||||
| '1 2 3 4 5 6 7 8 9 0 {bksp}', | |||||
| 'Q W E R T Y U I O P', | |||||
| 'A S D F G H J K L', | |||||
| 'Z X C V B N M {accept}' | |||||
| ] | |||||
| } | |||||
| }); | |||||
| // 定時自動更新頁面 | |||||
| (function autoReloadPage(){ | |||||
| var pageReloadTimeMillis = 60000; // 頁面, 自動重新載入週期 ( 1 min ) | |||||
| var pageCheckReloadTimeMillis = 10000; // 頁面, 判斷重新載入週期 ( 10 sec ) | |||||
| var pageShowReloadTimeMillis = 50000; // 頁面, 開始顯示倒數週期 ( 50 sec ) | |||||
| var aliveTime = moment(); | |||||
| var countdownTimeMillis = pageReloadTimeMillis; | |||||
| $(document.body).bind("mousemove keypress", function(e) { | |||||
| aliveTime = moment(); | |||||
| countdownTimeMillis = pageReloadTimeMillis; | |||||
| }); | |||||
| function refresh() { | |||||
| if(moment() - aliveTime >= pageReloadTimeMillis) // 如果頁面沒動作, 才更新 | |||||
| window.location.reload(true); | |||||
| else{ | |||||
| countdownTimeMillis -= pageCheckReloadTimeMillis; | |||||
| if(countdownTimeMillis < pageCheckReloadTimeMillis) | |||||
| { | |||||
| alertify_count_down("重新載入中..請稍候..", pageCheckReloadTimeMillis); | |||||
| } | |||||
| else if(countdownTimeMillis < pageShowReloadTimeMillis){ | |||||
| alertify_count_down("倒數: " + (countdownTimeMillis / 1000) + " 秒, 重新載入畫面..", pageCheckReloadTimeMillis); | |||||
| } | |||||
| setTimeout(refresh, pageCheckReloadTimeMillis); | |||||
| } | |||||
| } | |||||
| setTimeout(refresh, pageCheckReloadTimeMillis); | |||||
| })(); | |||||
| }); | |||||
| </script> | |||||