| @@ -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> | |||