소스 검색

北車 part1

station_14109
altobaltobaltob GitHub 8 년 전
부모
커밋
debefafc74
47개의 변경된 파일19304개의 추가작업 그리고 0개의 파일을 삭제
  1. +157
    -0
      config/constants.php
  2. +215
    -0
      controllers/Acer_service.php
  3. +1102
    -0
      controllers/Admins_station.php
  4. +574
    -0
      controllers/Allpa_service.php
  5. +260
    -0
      controllers/Allpay_invoice.php
  6. +413
    -0
      controllers/Allpay_payment.php
  7. +872
    -0
      controllers/Carpark.php
  8. +238
    -0
      controllers/Carpayment.php
  9. +234
    -0
      controllers/Cars.php
  10. +218
    -0
      controllers/Ctbcbank.php
  11. +163
    -0
      controllers/Parkingquery.php
  12. +204
    -0
      controllers/Payment.php
  13. +198
    -0
      controllers/Payment_ats.php
  14. +268
    -0
      controllers/Pks.php
  15. +242
    -0
      controllers/Qcar.php
  16. +104
    -0
      controllers/Txdata.php
  17. +353
    -0
      controllers/Vip.php
  18. +109
    -0
      controllers/Vip_parked.php
  19. +11
    -0
      controllers/index.html
  20. +250
    -0
      coworker/acer2server.php
  21. +322
    -0
      coworker/parktron2server_fuzzy.php
  22. +15
    -0
      coworker/station.config.php
  23. +439
    -0
      coworker/station_services.php
  24. +38
    -0
      coworker/sync_hq_daily.php
  25. +38
    -0
      coworker/sync_minutely.php
  26. +342
    -0
      models/Acer_service_model.php
  27. +896
    -0
      models/Admins_model.php
  28. +3041
    -0
      models/Admins_station_model.php
  29. +1606
    -0
      models/Allpa_service_model.php
  30. +1058
    -0
      models/Allpay_invoice_model.php
  31. +20
    -0
      models/Allpay_payment_model.php
  32. +596
    -0
      models/Carpark_model.php
  33. +653
    -0
      models/Carpayment_model.php
  34. +1281
    -0
      models/Cars_model.php
  35. +185
    -0
      models/Ctbcbank_model.php
  36. +265
    -0
      models/Excel_model.php
  37. +60
    -0
      models/Landb_model.php
  38. +194
    -0
      models/Parkingquery_model.php
  39. +167
    -0
      models/Payment_ats_model.php
  40. +185
    -0
      models/Payment_model.php
  41. +356
    -0
      models/Pks_model.php
  42. +349
    -0
      models/Qcar_model.php
  43. +84
    -0
      models/Security_model.php
  44. +715
    -0
      models/Sync_data_model.php
  45. +127
    -0
      models/Txdata_model.php
  46. +76
    -0
      models/User_model.php
  47. +11
    -0
      models/index.html

+ 157
- 0
config/constants.php 파일 보기

@@ -0,0 +1,157 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
|--------------------------------------------------------------------------
| File and Directory Modes
|--------------------------------------------------------------------------
|
| These prefs are used when checking and setting modes when working
| with the file system. The defaults are fine on servers with proper
| security, but you may wish (or even need) to change the values in
| certain environments (Apache running a separate process for each
| user, PHP under CGI with Apache suEXEC, etc.). Octal values should
| always be used to set the mode correctly.
|
*/
define('FILE_READ_MODE', 0644);
define('FILE_WRITE_MODE', 0666);
define('DIR_READ_MODE', 0755);
define('DIR_WRITE_MODE', 0777);
/*
|--------------------------------------------------------------------------
| File Stream Modes
|--------------------------------------------------------------------------
|
| These modes are used when working with fopen()/popen()
|
*/
define('FOPEN_READ', 'rb');
define('FOPEN_READ_WRITE', 'r+b');
define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care
define('FOPEN_WRITE_CREATE', 'ab');
define('FOPEN_READ_WRITE_CREATE', 'a+b');
define('FOPEN_WRITE_CREATE_STRICT', 'xb');
define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b');
/*end*/
// user define
// define('DEBUG_MODE', true);
define('APP_BASE', '/home/bigbang/apps/parkings/'); // 應用系統根路徑
define('FILE_BASE', '/home/data/parkings/'); // 檔案存取根路徑
define('CAR_PIC', FILE_BASE.'cars/pics/'); // 車輛照片存檔路徑
define('PKS_PIC', FILE_BASE.'pks/pics/'); // 車輛入車格照片存檔路徑
define('EXPORT_BASE', '/home/data/export/'); // 檔案匯出根路徑
define('STATION_NAME', '未設定'); // 本場站名稱
define('STATION_NO', 54321); // 本場站編號
define('STATION_IP', '192.168.0.201'); // 本場站IP
define('STATION_URL', 'http://'.STATION_IP.'/'); // 本場站URL
define('PHPLIBS_BASE', '/home/bigbang/libs/phplibs/'); // phplibs 根路徑
define('ALTOB_SYNC_FILE', PHPLIBS_BASE.'Altob.Sync.Integration.php'); // ALTOB (同步)
define('ALTOB_CRYPT_FILE', PHPLIBS_BASE.'Altob.Crypt.Integration.php'); // ALTOB (資料加解密)
define('ALTOB_BILL_FILE', PHPLIBS_BASE.'Altob.Payment.Integration.php'); // ALTOB (金流: 費率)
define('ALTOB_TWGC_FILE', PHPLIBS_BASE.'Altob.TWGC.Integration.php'); // ALTOB (歐Pa卡: TWGC)
define('ALTOB_CTBC_FILE', PHPLIBS_BASE.'ctbcbank/Altob.CTBC.Bank.Integration.php'); // 中國信託 (金流)
define('ALLPAY_FILE', PHPLIBS_BASE.'AllPay.Payment.Integration.php'); // 歐付寶 (金流)
define('ALLPAY_INVOICE_FILE', PHPLIBS_BASE.'AllPay_Invoice.php'); // 歐付寶 (電子發票)
define('MQ_CLASS_FILE', PHPLIBS_BASE.'phpMQTT.php'); // MQTT: class file name
define('MQ_HOST', '192.168.0.202'); // MQTT: host
define('MQ_PORT', 1883); // MQTT: port (default:1883)
define('MQ_TOPIC_SUBLEVEL', 'SUBLEVEL'); // MQTT TOPIC: 樓層在席顯示
define('MQ_TOPIC_SUBTEXT', 'SUBTEXT'); // MQTT TOPIC: 出入口字幕機
define('MQ_TOPIC_OPEN_DOOR', 'OPEN_DOOR'); // MQTT TOPIC: 出入口開門
define('MQ_TOPIC_ALTOB', 'altob.com.tw.mqtt'); // MQTT TOPIC: common mqtt topic
define('MQ_ALTOB_MSG', 'msg'); // MQTT TOPIC: cmd: msg
define('MQ_ALTOB_MSG_END_TAG', ',altob'); // MQTT TOPIC: cmd: msg end tag
define('MQ_ALTOB_888', '888'); // MQTT TOPIC: cmd: 888
define('MQ_ALTOB_888_END_TAG', ',altob'); // MQTT TOPIC: cmd: 888 end tag
define('MEMCACHE_HOST', 'localhost'); // memcache host
define('MEMCACHE_PORT', 11211); // memcache post no (default:11211)
// Date.timezone
//date_default_timezone_set("Asia/Taipei"); // <-- TODO: php.ini 無效 ?????????????????????????????????????????????
/*
|--------------------------------------------------------------------------
| 自定義連結 - 共用設定
|--------------------------------------------------------------------------
*/
define("ALTOB_PAYMENT_TXDATA_URL", "http://localhost/txdata.html"); // 費率 ServiceURL
/*
|--------------------------------------------------------------------------
| LOG檔名 - 共用設定
|--------------------------------------------------------------------------
*/
define("MEMBER_LOG_TITLE", 'member-log://'); // 會員資料記錄
define("TX_LOG_TITLE", 'tx-log://'); // 交易資料記錄
define("ADMIN_LOG_TITLE", 'admin-log://'); // 管理操作記錄
define("EXPORT_LOG_TITLE", 'export-log://'); // 檔案匯出記錄
/*
|--------------------------------------------------------------------------
| 資料庫欄位 - 共用設定
|--------------------------------------------------------------------------
*/
// member_tx.verify_state
define("MEMBER_TX_VERIFY_STATE_NONE", 0); // 0: 未審核
define("MEMBER_TX_VERIFY_STATE_OK", 1); // 1: 人工審核完成
define("MEMBER_TX_VERIFY_STATE_GG", 99); // 99: 審核不通過
// member_tx.tx_state
define("MEMBER_TX_TX_STATE_NONE", 0); // 0: 無
define("MEMBER_TX_TX_STATE_STOP", 4); // 4: 已退租
define("MEMBER_TX_TX_STATE_CANCEL", 44); // 44: 交易取消
// member_tx_bill.invoice_state
define("MEMBER_TX_BILL_INVOICE_STATE_NONE", 0); // 0: 無
define("MEMBER_TX_BILL_INVOICE_STATE_MORE", 1); // 1: 待補開
define("MEMBER_TX_BILL_INVOICE_STATE_ALLOWANCE", 2); // 2: 待折讓
define("MEMBER_TX_BILL_INVOICE_STATE_MORE_DONE", 91); // 91: 補開完成
define("MEMBER_TX_BILL_INVOICE_STATE_ALLOWANCE_DONE", 92); // 92: 折讓完成
// member_refund.refund_state
define("MEMBER_REFUND_STATE_NONE", 0); // 0: 無
define("MEMBER_REFUND_STATE_MORE_INVOICE", 1); // 1: 待補開
define("MEMBER_REFUND_STATE_LESS_INVOICE", 2); // 2: 待折讓
define("MEMBER_REFUND_STATE_DONE", 100); // 100: 已完成
// member_refund.dismiss_state
define("MEMBER_REFUND_DISMISS_STATE_NONE", 0); // 0: 無
define("MEMBER_REFUND_DISMISS_STATE_TRANSFERRED", 1); // 1: 已轉租
define("MEMBER_REFUND_DISMISS_STATE_KEEP_DEPOSIT", 10); // 10: 押金未退
define("MEMBER_REFUND_DISMISS_STATE_DONE", 100); // 100: 已結清
// tx_bill_ats.status
define("TX_BILL_ATS_STATUS_NONE", 0); // 0: 剛建立
define("TX_BILL_ATS_STATUS_PAID", 1); // 1: 結帳完成
define("TX_BILL_ATS_STATUS_INVOICE_VOID", 104); // 104: 發票已作廢
define("TX_BILL_ATS_STATUS_INVOICE_ALLOWANCE", 105); // 105: 發票已折讓
// tx_bill.status
define("TX_BILL_STATUS_NONE", 0); // 0: 剛建立
define("TX_BILL_STATUS_PAID", 1); // 1: 結帳完成
define("TX_BILL_STATUS_ERROR_AMT", 2); // 2: 錢沒對上
define("TX_BILL_STATUS_ERROR_INVOICE", 3); // 3: 發票沒建立
define("TX_BILL_STATUS_HAND_MODE", 4); // 4: 手動調整
define("TX_BILL_STATUS_TIME_OUT", 99); // 99: 訂單逾期作廢
define("TX_BILL_STATUS_PROCESSING", 100); // 100: 交易進行中
define("TX_BILL_STATUS_FAIL", 101); // 101: 交易失敗
define("TX_BILL_STATUS_DONE", 111); // 111: 產品已領取
/* End of file constants.php */
/* Location: ./application/config/constants.php */

+ 215
- 0
controllers/Acer_service.php 파일 보기

@@ -0,0 +1,215 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
file: Acer_service.php 與 acer 介接相關都放這支
*/
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'acer_service'); // 應用系統名稱
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/acer_service.'); // log file name
class Acer_service extends CI_Controller
{
var $vars = array();
function __construct()
{
parent::__construct();
$method_name = $this->router->fetch_method();
if (in_array($method_name, array('cmd_101', 'cmd_102')))
{
ob_end_clean();
ignore_user_abort();
ob_start();
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
}
ignore_user_abort(); // 接受client斷線, 繼續run
$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; // 本站編號
// session_id(ip2long($_SERVER['REMOTE_ADDR'])); // 設定同一device為同一個session
session_start();
// ----- 程式開發階段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('acer_service_model');
$this->acer_service_model->init($this->vars);
// 阻檔未知的 IP
if(!in_array($_SERVER['HTTP_X_REAL_IP'], array('127.0.0.1')))
{
trigger_error('refused://from:'.$_SERVER['HTTP_X_REAL_IP'].'..refused..');
exit;
}
}
// 發生錯誤時集中在此處理
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代表參考後面的檔名
}
// 顯示logs
public function show_logs()
{
$lines = $this->uri->segment(3); // 顯示行數
if (empty($lines)) $lines = 100; // 無行數參數, 預設為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_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 利用linux指令顯示倒數幾行的logs內容
echo "\n----- " . LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt' . ' -----';
echo '</pre></body></html>';
}
// 票卡入場訊號,供 ALTOB 登記
public function cmd_001()
{
$card_no = $this->input->post('card_no', true);
$cario_no = $this->input->post('cario_no', true);
$card_type = $this->input->post('card_type', true);
trigger_error(__FUNCTION__ . ", card_no:{$card_no}, cario_no:{$cario_no}, card_type:{$card_type}");
$data = $this->acer_service_model->cmd_001($card_no, $cario_no, $card_type);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 票卡離場訊號,供 ALTOB 登記
public function cmd_002()
{
$card_no = $this->input->post('card_no', true);
$pay_time = $this->input->post('pay_time', true);
$card_type = $this->input->post('card_type', true);
trigger_error(__FUNCTION__ . ", card_no:{$card_no}, pay_time:{$pay_time}, card_type:{$card_type}");
$data = $this->acer_service_model->cmd_002($card_no, $pay_time, $card_type);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 票號離場訊號,回傳若成功觸發 ACER 開門
public function cmd_003()
{
$ticket_no = $this->input->post('ticket_no', true);
trigger_error(__FUNCTION__ . ", ticket_no:{$ticket_no}");
$data = $this->acer_service_model->cmd_003($ticket_no);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 車辨入場訊號,觸發 ACER 開門
public function cmd_101()
{
$cario_no = $this->input->post('cario_no', true);
$in_time = $this->input->post('in_time', true);
$ticket_no = $this->input->post('ticket_no', true);
$lpr = $this->input->post('lpr', true);
$ivs_no = $this->input->post('ivs_no', true);
trigger_error(__FUNCTION__ . ", cario_no:{$cario_no}, in_time:{$in_time}, ticket_no:{$ticket_no}, lpr:{$lpr}, ivs_no:{$ivs_no}");
$data = $this->acer_service_model->cmd_101($cario_no, $in_time, $ticket_no, $lpr, $ivs_no);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 車辨離場訊號,觸發 ACER 開門 (若入場編號為 0, 表示車辨失敗)
public function cmd_102()
{
$cario_no = $this->input->post('cario_no', true);
$ivs_no = $this->input->post('ivs_no', true);
$msg_code = $this->input->post('msg_code', true);
/* msg_code:
1 離場車辨失敗
2 離場會員鎖車
5 會員車離場
6 臨停車離場 (時間內離場, 已繳費)
7 臨停車離場 (超過離場時限, 歐pa卡繳費)
8 臨停車未付款 (時間內離場, 無繳費)
9 臨停車未付款 (超過離場時限, 非歐pa卡會員)
10 會員車離場 (無入場資料)
12 臨停車未付款 (超過離場時限, 歐pa卡餘額不足)
13 無入場記錄
16 時段月租戶超時(月租)
*/
trigger_error(__FUNCTION__ . ", cario_no:{$cario_no}, ivs_no:{$ivs_no}, msg_code:{$msg_code}");
$data = $this->acer_service_model->cmd_102($cario_no, $ivs_no, $msg_code);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 測試 acer cmd 101
public function test_acer_cmd_101()
{
// input
$cario_no = '1234567890'; // 入場編號: 10 碼
$in_time = '2017-04-25 15:15:15'; // 入場時間: 19碼
$ticket_no = '123456'; // 六碼數字
$lpr = 'ABC123';
$ivsno = 1; // 車道編號
$data = $this->acer_service_model->cmd_101($cario_no, $in_time, $ticket_no, $lpr, $ivsno);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 測試 acer cmd 102
public function test_acer_cmd_102()
{
// input
$cario_no = '1234567890'; // 入場編號: 10 碼
$ivsno = 1; // 車道編號
$data = $this->acer_service_model->cmd_102($cario_no, $ivsno);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
}

+ 1102
- 0
controllers/Admins_station.php
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 574
- 0
controllers/Allpa_service.php 파일 보기

@@ -0,0 +1,574 @@
<?php
/*
file: Allpa_service.php (歐Pa卡)
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Allpa_service extends CI_Controller
{
var $vars = array(); // 共用變數
function __construct()
{
parent::__construct();
$method_name = $this->router->fetch_method();
if ($method_name == 'allpa_consume_handler')
{
ob_end_clean();
ignore_user_abort();
ob_start();
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
}
// ----- 程式開發階段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->vars['mcache'] = new Memcache;
$this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_PORT) or die ('Could not connect memcache');
// 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', 'allpa_service'); // 應用系統名稱
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
$this->load->model('allpa_service_model'); // 歐Pa卡
$this->load->model('allpay_invoice_model'); // 歐付寶電子發票
// ----- 中國信託金流 -----
$this->load->model('ctbcbank_model'); // 中國信託金流
define('CTBC_AuthResURL', APP_URL."return_ok/"); // 從收單行端取得授權碼後,要導回的網址,請勿填入特殊字元@、#、%、?、&等。
// ----- 中國信託金流 (end) -----
// ----- 頁面 -----
define('MAIN_PAGE', "main_page");
define('RESULT_PAGE', "result_page");
define('ERROR_PAGE', "error_page");
define('ADMIN_PAGE', "admin_page");
define('ADMIN_LOGIN_PAGE', "admin_login_page");
define('ADMIN_RESULT_PAGE', "admin_result_page");
// ----- 頁面 -----
// [START] 2016/06/08 登入
$this->load->model('user_model');
// load library
$this->load->library(array('form_validation','session'));
// load helpers
$this->load->helper(array('form'));
// ajax code
define('RESULT_SUCCESS', 'ok');
define('RESULT_FORM_VALIDATION_FAIL', '-1');
define('RESULE_FAIL', 'gg');
// [END] 2016/06/08 登入
}
// 發生錯誤時集中在此處理
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代表參考後面的檔名
//echo "whoami: ".`whoami`;
//echo "<br/>".$str;
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);
}
}
// [START] 2016/06/08
// ADMIN.1 管理者頁面
public function admin()
{
if($this->session->userdata('logged_in'))
{
$session_data = $this->session->userdata('logged_in');
$data['username'] = $session_data['username'];
$data['type'] = $session_data['type'];
if($data['type'] == 'admin')
{
$this->show_page('NOT_READY___', $data); // 進階管理者介面 (TODO)
}
else
{
$this->show_page(ADMIN_PAGE, $data); // 一般
}
}
else
{
$this->show_page(ADMIN_LOGIN_PAGE);
}
}
// ADMIN.2.a 管理者頁面登入
public function user_login()
{
// form_validation
$this->form_validation->set_rules('login_name', 'login_name', 'trim|required');
$this->form_validation->set_rules('pswd', 'pswd', 'trim|required');
if($this->form_validation->run() == FALSE)
{
return RESULT_FORM_VALIDATION_FAIL;
}
// go model
$data = array
(
'login_name' => $this->input->post('login_name', true),
'pswd' => $this->input->post('pswd', true)
);
$result = $this->user_model->user_login($data);
if($result)
{
$sess_array = array();
foreach($result as $row)
{
$sess_array = array
(
'username' => $row->login_name ,
'type' => $row->user_type
);
$this->session->set_userdata('logged_in', $sess_array);
}
echo RESULT_SUCCESS;
}
else
{
return RESULE_FAIL;
}
}
// ADMIN.2.b 管理者頁面登出
public function user_logout()
{
if(!$this->session->userdata('logged_in')){echo json_encode(null, JSON_UNESCAPED_UNICODE);return;} // 沒登入就回傳null
$this->session->unset_userdata('logged_in');
session_destroy();
return RESULT_SUCCESS;
}
// ADMIN.3.a 管理者產品列表
// http://203.75.167.89/allpa_service.html/get_allpa_admin_products
public function get_allpa_admin_products()
{
if(!$this->session->userdata('logged_in')){echo json_encode(null, JSON_UNESCAPED_UNICODE);return;} // 沒登入就回傳null
$data = $this->allpa_service_model->get_allpa_admin_products();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// ADMIN.3.b 產品列表 - 購買管理者產品
public function purchase_admin_products()
{
if(!$this->session->userdata('logged_in')){echo json_encode(null, JSON_UNESCAPED_UNICODE);return;} // 沒登入就回傳null
$product_id = $this->input->post('product_id', true);
$data = $this->allpa_service_model->create_admin_bill($product_id);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// ADMIN.3.c 管理者結帳
public function transfer_money_admin()
{
if(!$this->session->userdata('logged_in')){echo json_encode(null, JSON_UNESCAPED_UNICODE);return;} // 沒登入就回傳null
$lpr = strtoupper($this->uri->segment(3)); // 車牌號碼
$order_no = strtoupper($this->uri->segment(4)); // 交易序號
$invoice_receiver = urldecode($this->uri->segment(5)); // 載具編號 (可有可無)
$company_no = urldecode($this->uri->segment(6)); // 載具編號 (可有可無)
$email_base64 = $this->uri->segment(7); // 電子信箱
$mobile = $this->uri->segment(8); // 手機號碼
// decode email
if(strlen($email_base64) > 0){
$email = base64_decode($email_base64.'='); // base64字串尾端的'='還原
}else{
$email = email_base64;
}
$data = $this->allpa_service_model->pay_bill($lpr, $order_no, $invoice_receiver, $company_no, $email, $mobile); // 記錄訂單設定
// 管理員結帳流程
if (!empty($data)){
$data = $this->allpa_service_model->get_product_bill($order_no);
if (!empty($data)){
$order_no = $data['order_no'];
$lpr = $data['lpr'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
// 先記錄
$this->allpa_service_model->transfer_money_done($order_no);
// 開立歐付寶電子發票
$this->allpay_invoice_model->invoice_issue_for_product_bill($order_no, $amt);
// 直接開卡
$this->allpa_service_model->activate_bill_for_new_register($order_no);
// 交易成功
$this->show_page(ADMIN_RESULT_PAGE);
break;
default:
// 對方多傳一次時??
trigger_error(__FUNCTION__.', order_no=>' . $order_no.'<br>'.'status != 100');
}
}
}
}
// [END] 2016/06/08
// 首頁
public function index()
{
$this->show_page(MAIN_PAGE);
}
// 管理
/*
public function admin()
{
$this->show_page(ADMIN_PAGE);
}
*/
// A.1 查詢, 用戶歐Pa卡資訊
// http://203.75.167.89/allpa_service.html/get_allpa_info
public function get_allpa_info()
{
$user_lpr = strtoupper($this->input->post('user_lpr', true));
$data = $this->allpa_service_model->get_allpa_info($user_lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// A.2 卡片查詢 (API)
public function get_barcode_info()
{
$barcode = $this->input->post('barcode', true);
$result = $this->allpa_service_model->get_barcode_info($barcode);
echo json_encode($result, JSON_UNESCAPED_UNICODE);
}
// A.3 卡片記名 (API)
public function card_register()
{
$lpr = strtoupper($this->input->post('lpr', true));
$barcode = $this->input->post('barcode', true);
$result = $this->allpa_service_model->card_register($lpr, $barcode);
echo json_encode($result, JSON_UNESCAPED_UNICODE);
}
// B.1 啟用, 產品
public function activate_bill()
{
$order_no = $this->input->post('order_no', true);
$data = $this->allpa_service_model->activate_bill($order_no);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// B.2 儲值
public function allpa_reload()
{
$order_no = $this->input->post('order_no', true);
$reload_pin = $this->input->post('reload_pin', true);
$pin_check_id = $this->input->post('pin_check_id', true);
$data = $this->allpa_service_model->allpa_reload($order_no, $reload_pin, $pin_check_id);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// B.3 扣款
public function allpa_pay_bill()
{
$order_no = $this->input->post('order_no', true);
$data = $this->allpa_service_model->allpa_pay_bill($order_no);
if(! $data["result_code"]){
$data = $this->allpa_service_model->get_allpa_info($data["lpr"]);
}
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// C.1 產品列表
// http://203.75.167.89/allpa_service.html/get_allpa_products
public function get_allpa_products()
{
$data = $this->allpa_service_model->get_allpa_products();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// C.2 產品列表 - 購買
public function purchase()
{
$product_id = $this->input->post('product_id', true);
$data = $this->allpa_service_model->create_bill($product_id);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// C.3 付款
public function transfer_money()
{
$lpr = strtoupper($this->uri->segment(3)); // 車牌號碼
$order_no = strtoupper($this->uri->segment(4)); // 交易序號
$invoice_receiver = urldecode($this->uri->segment(5)); // 載具編號 (可有可無)
$company_no = urldecode($this->uri->segment(6)); // 載具編號 (可有可無)
$email_base64 = $this->uri->segment(7); // 電子信箱
$mobile = $this->uri->segment(8); // 手機號碼
// decode email
if(strlen($email_base64) > 0){
$email = base64_decode($email_base64.'='); // base64字串尾端的'='還原
}else{
$email = email_base64;
}
$data = $this->allpa_service_model->pay_bill($lpr, $order_no, $invoice_receiver, $company_no, $email, $mobile); // 記錄訂單設定
if (!empty($data)){
$this->ctbcbank_model->transfer_money_ctbc($data, CTBC_AuthResURL); // 中國信託
}
}
// C.4 收單行端取得授權碼後,要導回的網址 (call by CTBC)
public function return_ok()
{
/**
=======ALL_REQUEST======
URLResEnc: AF2100C51A9E844A1E820B953EA512BE49286403253FF9373474F6AE4A5877B084DD4D9B20F03AF0F34DB3D42A9C583938FE5DC1B60C53384864D9581EE997F92552A2F516B04F2FB2FE3E5C10D61CE84C5B63B87379F1048E16AC430AE94989724D8B0087734F73BF40CE904A05D555F526E5A93462C42931A0A7EC1E6AFF8BC39E641A8F5EE8882BD5B02F838BC217A87533AB9FE98CE1DD558B3CC345FC77D06C1783067F75DF94C58B55A826CD33B32355439BF3C9F17A4596138942B4457B66EB8FA09749C246D5B91799FB3942EC90138033272D89861B8698398FF4F3010628C0D11C7D88FB7A5F85CC59717D9F8D5CADBA5A1231E0396AE344B1DA139BA84F9D477E53A73A376BFCC92B52619E3B396BB28ABE7C4CEE3D3ED2CA1BEEF466F2D645C5CBF1C678C5747BA2A048F2F0FC2B86CAE379DE7A7F144D07C31A
merID: 10063
----------------------------END
*/
// 取得回傳資訊
foreach ($_REQUEST as $key => $value) {
switch ($key){
case "URLResEnc": $resenc = $value; break;
case "merID": $merid = $value; break;
}
}
if(! empty($resenc)){
$return_data = $this->ctbcbank_model->ctbcbank_return_handler($resenc, $merid);
$ctbc_lidm = $return_data['lidm'];
$ctbc_authamt = $return_data['authamt'];
$ctbc_status = $return_data['status'];
if($ctbc_status != 0){
// 金流處理失敗
$this->allpa_service_model->transfer_money_done_with_tx_error($order_no);
}else if(! empty($ctbc_lidm)) {
$data = $this->allpa_service_model->get_product_bill($ctbc_lidm);
if (! empty($data)) {
$order_no = $data['order_no'];
$lpr = $data['lpr'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
// 印發票流程
if($ctbc_authamt == $amt){
// 先記錄
$this->allpa_service_model->transfer_money_done($order_no);
// 開立歐付寶電子發票
$this->allpay_invoice_model->invoice_issue_for_product_bill($order_no, $amt);
// 直接開卡
$this->allpa_service_model->activate_bill_for_new_register($order_no);
// 交易成功
$this->show_page(RESULT_PAGE);
return;
}else{
// 錢沒對上
$this->allpa_service_model->transfer_money_done_with_amt_error($order_no);
}
break;
default:
// 對方多傳一次時??
trigger_error(__FUNCTION__.', order_no=>' . $order_no.'<br>'.'status != 100');
}
}else{
// 我們自己找不到記錄時??
trigger_error(__FUNCTION__.', order_no=>' . $order_no.'<br>'.' NOT FOUND !!');
}
}else{
// 回傳沒有資料 lidm
trigger_error(__FUNCTION__.', ERROR ..lidm=>' . $ctbc_lidm);
}
}else{
// 回傳沒有資料 resenc
trigger_error(__FUNCTION__.', ERROR ..resenc=>' . $resenc);
}
// 交易失敗
$this->show_page(ERROR_PAGE);
}
// L.1 歐Pa卡 - 開門 (限制存取)
// http://203.75.167.89/allpa_service.html/allpa_go/1458699630/QQQ/12112/5dfe0856f3cdf67772710c3e7e805b80
// http://203.75.167.89/allpa_service.html/allpa_go/1458714030/EEE/12112/19dd4f6692057ad897dc4e0290183a58
// http://203.75.167.89/allpa_service.html/allpa_go/1458714030/YYY/12112/efb076ad1c1d615e6db8c718c116d2d2
// http://203.75.167.89/allpa_service.html/allpa_go/1458714030/MMM/12112/4da21617852b4b43b86f8ac36f9db3e5
// http://203.75.167.89/allpa_service.html/allpa_go/1458714030/BBB/12112/335f61a2a90ba3277cfe0f4cd1a07e26 // KO
// http://203.75.167.89/allpa_service.html/allpa_go/1458897030/KKK/12112/b72332e2939a1a3152aa9d31ef945952
// http://203.75.167.89/allpa_service.html/allpa_go/1459078230/SAYLXXX/12112/5dd8036423fa8eeb7115cd4249327e08
public function allpa_go()
{
$in_time = $this->uri->segment(3); // 進場時間
$lpr = $this->uri->segment(4); // 車牌號碼
$station_no = $this->uri->segment(5); // 場站編號
$check_mac = $this->uri->segment(6); // 驗証欄位
ob_end_clean();
ignore_user_abort();
ob_start();
$data = $this->allpa_service_model->allpa_go($in_time, $lpr, $station_no, $check_mac); // 開門
echo json_encode($data, JSON_UNESCAPED_UNICODE);
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
// 呼叫: 非同步扣款流程
if(!$data["result_code"]){
file_get_contents(APP_URL."allpa_consume_handler/{$data["order_no"]}");
}
}
// L.2 歐Pa卡 - 非同步扣款 (限制存取)
public function allpa_consume_handler()
{
$order_no = $this->uri->segment(3); // 訂單編號
$this->allpa_service_model->allpa_pay_bill($order_no); // 扣款
//sleep(5); // test delay
exit();
}
// L.3 歐Pa卡 - 判斷有效用戶 (限制存取)
public function get_allpa_valid_user()
{
$lpr = $this->uri->segment(3); // 車牌號碼
$check_mac = $this->uri->segment(4); // 驗証欄位
ob_end_clean();
ignore_user_abort();
ob_start();
$data = $this->allpa_service_model->get_allpa_valid_user($lpr, $check_mac); // check user
echo json_encode($data, JSON_UNESCAPED_UNICODE);
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
}
// only test
public function gen_test_link()
{
$in_time = strtotime("2016-03-29 16:50:00");
$lpr = "SAYLXXX";
$station_no = "12112";
echo "TEST: ".APP_URL."allpa_go/{$in_time}/{$lpr}/{$station_no}/".md5($in_time.$lpr.$station_no);
echo "<br/>";
echo "TEST: ".APP_URL."get_allpa_valid_user/{$lpr}/".md5($lpr);
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
}
}

+ 260
- 0
controllers/Allpay_invoice.php 파일 보기

@@ -0,0 +1,260 @@
<?php
/*
file: Allpay_invoice.php 歐付寶電子發票
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'allpay_invoice'); // 應用系統名稱
define('PAGE_PATH', APP_BASE.'ci_application/views/'.APP_NAME.'/'); // path of views
define('SERVER_URL', 'http://'.$_SERVER['HTTP_HOST'].'/'); // URL
define('WEB_SERVICE', 'http://'.$_SERVER['SERVER_NAME'].':60133/?'); // web service port:60133
define('WEB_LIB', SERVER_URL.'libs/'); // 網頁lib
define('BOOTSTRAPS', WEB_LIB.'bootstrap_sb/'); // bootstrap lib
define('APP_URL', SERVER_URL.APP_NAME.'.html/'); // controller路徑
define('WEB_URL', SERVER_URL.APP_NAME.'/'); // 網頁路徑
define('LOG_PATH', FILE_BASE.APP_NAME.'/logs/'); // log path
class Allpay_invoice 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('allpay_invoice_model');
}
// 發生錯誤時集中在此處理
public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
// ex: car_err://message....
$log_msg = explode('://', $errstr);
if (count($log_msg) > 1)
{
$log_file = LOG_PATH.$log_msg[0];
$str = date('H:i:s')."|{$log_msg[1]}|{$errfile}|{$errline}|{$errno}\n";
}
else
{
$log_file = LOG_PATH.APP_NAME;
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
}
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
error_log($str, 3, $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);
/*
// Cross-Origin Resource Sharing Header(允許跨網域連線)
header('Access-Control-Allow-Origin: ' . SERVER_URL);
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept');
*/
// 若檔案修改時間沒有異動, 或版本無異動, 通知瀏覽器使用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');
}
/*
// step 1: 建立待開記錄
public function test_step1()
{
$station_no = 54321;
$tx_bill_no = 12;
$amt = 1600;
$data = $this->allpay_invoice_model->test_step1_init_bill($station_no, $tx_bill_no, $amt);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// step 2: 開立發票參數
public function test_step2()
{
$order_no = '14906858560000000012';
$company_no = 0;
$email = 'saylxxx@gmail.com';
$mobile = '0953034986';
$invoice_receiver = 0;
$data = $this->allpay_invoice_model->test_step2_submit_purchase($order_no, $company_no, $email, $mobile, $invoice_receiver);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// step 1: 建立待開記錄與參數
public function test_step1_step2_submit()
{
$station_no = 54321;
$tx_bill_no = 12;
$amt = 1600;
$company_no = 0;
$email = 'saylxxx@gmail.com';
$mobile = '0953034986';
$invoice_receiver = 0;
$data = $this->allpay_invoice_model->test_step1_step2_submit(
$station_no, $tx_bill_no, $amt,
$company_no, $email, $mobile, $invoice_receiver);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// step 3: 開立發票
public function test_step3()
{
$order_no = '14906866680000000012';
$amt = 1600;
$data = $this->allpay_invoice_model->invoice_issue_for_tx_bill_ats($order_no, $amt);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 測試:M.1 建立月租系統發票待開記錄
public function test_create_member_tx_bill_record()
{
$station_no = 54321;
$tx_bill_no = 12;
$amt = 1600;
$company_no = 0;
$email = 'saylxxx@gmail.com';
$mobile = '0953034986';
$data = $this->allpay_invoice_model->create_member_tx_bill_record($station_no, $tx_bill_no, $amt, $company_no, $email, $mobile);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// 回傳, 要記下 order_no
// {"invoice_remark":"停車費用帳單","order_no":"14906884740000000012","station_no":54321,"amt":1600,"email":"saylxxx@gmail.com","mobile":"0953034986","status":1,"tx_time":"2017\/03\/28 16:07:54","tx_type":100}
}
// 測試:M.2 開立月租系統待開發票
public function test_create_member_tx_bill_invoice()
{
$order_no = '14906884740000000012';
$amt = 1600;
$data = $this->allpay_invoice_model->create_member_tx_bill_invoice($order_no, $amt);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// 回傳
// {"invoice_no":"TM00012802","result_code":"OK","result_msg":"成功"}
}
// 測試:作廢發票
public function test_invoice_void()
{
$invoice_no = 'TM00012665';
$reason_str = 'test';
$data = $this->allpay_invoice_model->invoice_void($invoice_no, $reason_str);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 測試:作廢月租系統發票
public function test_void_member_tx_bill_invoice()
{
$station_no = "54321";
$order_no = "14906958880000000025";
$invoice_no = "TM00012805";
$data = $this->allpay_invoice_model->void_member_tx_bill_invoice($station_no, $order_no, $invoice_no);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 測試:開立折讓
public function test_invoice_allowance()
{
$invoice_no = 'TM00012665';
$allowance_amt = 1600;
$data = $this->allpay_invoice_model->invoice_allowance($invoice_no, $allowance_amt);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
*/
public function test_curl()
{
$station_no = 54321;
$tx_bill_no = 25;
$amt = 2640;
$company_no = 0;
$email = 'saylxxx@gmail.com';
$mobile = '0953034986';
$data = $this->allpay_invoice_model->test_curl($station_no, $tx_bill_no, $amt, $company_no, $email, $mobile);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 開立月租系統發票
public function create_member_tx_bill_invoice()
{
$station_no = $this->input->post('station_no', true); // 場站編號
$tx_bill_no = $this->input->post('tx_bill_no', true); // 會員交易帳單代號
$amt = $this->input->post('amt', true); // 金額
$member_company_no = $this->input->post('member_company_no', true); // 買方統編
$company_no = $this->input->post('company_no', true); // 賣方統編
$email = $this->input->post('email', true); // 通知信箱
$mobile = $this->input->post('mobile', true); // 通知簡訊
$lpr = $this->input->post('lpr', true); // 車牌號碼
$data = $this->allpay_invoice_model->create_member_tx_bill_invoice($station_no, $tx_bill_no, $amt, $member_company_no, $company_no, $email, $mobile, $lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 作廢月租系統發票
public function void_member_tx_bill_invoice()
{
$station_no = $this->input->post('station_no', true); // 場站編號
$order_no = $this->input->post('order_no', true); // 訂單編號
$invoice_no = $this->input->post('invoice_no', true); // 發票號碼
$data = $this->allpay_invoice_model->void_member_tx_bill_invoice($station_no, $order_no, $invoice_no);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 折讓月租系統發票
public function allowance_member_tx_bill_invoice()
{
$station_no = $this->input->post('station_no', true); // 場站編號
$invoice_no = $this->input->post('invoice_no', true); // 發票號碼
$allowance_amt = $this->input->post('allowance_amt', true); // 折讓金額
$data = $this->allpay_invoice_model->allowance_member_tx_bill_invoice($station_no, $invoice_no, $allowance_amt);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 測試:作廢折讓
public function test_allowance_void()
{
$invoice_no = 'TM00012665';
$allowance_no = '2017032814257398';
$reason_str = 'test';
$data = $this->allpay_invoice_model->allowance_void($invoice_no, $allowance_no, $reason_str);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
}

+ 413
- 0
controllers/Allpay_payment.php 파일 보기

@@ -0,0 +1,413 @@
<?php
/*
file: Allpay_payment.php 付費系統 (歐付寶)
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once(ALLPAY_FILE);
class Allpay_payment 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
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'allpay_payment'); // 應用系統名稱
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
$this->load->model('allpay_payment_model');
$this->load->model('payment_model'); // 一般臨停帳單 (tx_bill)
$this->load->model('payment_ats_model'); // 月租繳費機帳單 (tx_bill_ats)
/*
// ----- 正式環境 -----
define('ALLPAY_ServiceURL', "https://payment.ecpay.com.tw/Cashier/AioCheckOut"); // 您要呼叫的服務位址 (綠界)
//define('ALLPAY_ServiceURL', "https://payment.allpay.com.tw/Cashier/AioCheckOut"); // 您要呼叫的服務位址
define('ALLPAY_HashKey', "tLBnwUiKlbB0e6sS"); // AllPay提供給您的Hash Key
define('ALLPAY_HashIV', "bMhtNluToYSYoJBw"); // AllPay提供給您的Hash IV
define('ALLPAY_MerchantID', "1148391"); // AllPay提供給您的特店編號
// ----- 正式環境(end) -----
*/
// ----- 測試環境 -----
define('ALLPAY_ServiceURL', "http://payment-stage.allpay.com.tw/Cashier/AioCheckOut"); // 您要呼叫的服務位址
define('ALLPAY_HashKey', "5294y06JbISpM5x9"); // AllPay提供給您的Hash Key
define('ALLPAY_HashIV', "v77hoKGq4kWxNNIS"); // AllPay提供給您的Hash IV
define('ALLPAY_MerchantID', "2000132"); // AllPay提供給您的特店編號
// ----- 測試環境(end) -----
}
// 發生錯誤時集中在此處理
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代表參考後面的檔名
}
// 付款 (tx_bill)
public function transfer_money_tx_bill()
{
$order_no = $this->uri->segment(3); // 序號
try{
// 0. check tx_bill
$data = $this->payment_model->get_tx_bill($order_no);
if (! empty($data))
{
$status = $data['status'];
switch($status){
case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
$oPayment = new AllInOne();
$oPayment->ServiceURL = ALLPAY_ServiceURL;
$oPayment->HashKey = ALLPAY_HashKey;
$oPayment->HashIV = ALLPAY_HashIV;
$oPayment->MerchantID = ALLPAY_MerchantID;
/* 基本參數 */
$oPayment->Send['ReturnURL'] = STATION_URL.APP_NAME.'.html/tx_bill_finished/'; // 您要收到付款完成通知的伺服器端網址(server)
$oPayment->Send['ClientBackURL'] = $data['client_back_url']; // 您要歐付寶返回按鈕導向的瀏覽器端網址";
$oPayment->Send['OrderResultURL'] = $data['order_result_url']; // 您要收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來;
$oPayment->Send['MerchantTradeNo'] = $data['order_no']; // 您此筆訂單交易編號
$oPayment->Send['MerchantTradeDate'] = date('Y/m/d H:i:s', strtotime($data['tx_time'])); // 交易時間
$oPayment->Send['TotalAmount'] = (int) $data['amt']; // 您此筆訂單的交易總金額
$oPayment->Send['TradeDesc'] = $data['invoice_remark']; // 您該筆訂單的描述
$oPayment->Send['ChoosePayment'] = PaymentMethod::ALL; // PaymentMethod::WebATM;
$oPayment->Send['Remark'] = "";
$oPayment->Send['ChooseSubPayment'] = PaymentMethodItem::None;
$oPayment->Send['NeedExtraPaidInfo'] = ExtraPaymentInfo::No;
$oPayment->Send['DeviceSource'] = DeviceType::Mobile; //DeviceType::PC;
//$oPayment->Send['IgnorePayment'] = "Alipay#Tenpay"; //"<<您不要顯示的付款方式>>"; // 例(排除支付寶與財富通): Alipay#Tenpay
// 加入選購商品資料。
array_push($oPayment->Send['Items'],
array(
'Name' => "結算",
'Price' => (int)$data['amt'],
'Currency' => "元",
'Quantity' => (int) "1",
'URL' => "http://www.altob.com.tw" // 網址是做什麼用的 ?
)
);
/* 產生訂單 */
$oPayment->CheckOut();
/* 產生訂單 Html Code 的方法 */
$szHtml = $oPayment->CheckOutString();
default:
$sMsg = 'status != 100';
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
echo $sMsg;
}
}
}catch (Exception $e){
// 例外錯誤處理。
$sMsg = $e->getMessage();
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
echo $sMsg;
}
}
// 付款 (tx_bill_ats)
public function transfer_money_tx_bill_ats()
{
$order_no = $this->uri->segment(3); // 序號
try{
// 0. check tx_bill
$data = $this->payment_ats_model->get_tx_bill($order_no);
if (! empty($data))
{
$status = $data['status'];
switch($status){
case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
$oPayment = new AllInOne();
$oPayment->ServiceURL = ALLPAY_ServiceURL;
$oPayment->HashKey = ALLPAY_HashKey;
$oPayment->HashIV = ALLPAY_HashIV;
$oPayment->MerchantID = ALLPAY_MerchantID;
/* 基本參數 */
$oPayment->Send['ReturnURL'] = STATION_URL.APP_NAME.'.html/tx_bill_ats_finished/'; // 您要收到付款完成通知的伺服器端網址(server)
$oPayment->Send['ClientBackURL'] = $data['client_back_url']; // 您要歐付寶返回按鈕導向的瀏覽器端網址";
$oPayment->Send['OrderResultURL'] = $data['order_result_url']; // 您要收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來;
$oPayment->Send['MerchantTradeNo'] = $data['order_no']; // 您此筆訂單交易編號
$oPayment->Send['MerchantTradeDate'] = date('Y/m/d H:i:s', strtotime($data['tx_time'])); // 交易時間
$oPayment->Send['TotalAmount'] = (int) $data['amt']; // 您此筆訂單的交易總金額
$oPayment->Send['TradeDesc'] = $data['invoice_remark']; // 您該筆訂單的描述
$oPayment->Send['ChoosePayment'] = PaymentMethod::WebATM; //PaymentMethod::ALL;;
$oPayment->Send['Remark'] = "";
$oPayment->Send['ChooseSubPayment'] = PaymentMethodItem::None;
$oPayment->Send['NeedExtraPaidInfo'] = ExtraPaymentInfo::No;
$oPayment->Send['DeviceSource'] = DeviceType::PC; //DeviceType::Mobile;
//$oPayment->Send['IgnorePayment'] = "Alipay#Tenpay"; //"<<您不要顯示的付款方式>>"; // 例(排除支付寶與財富通): Alipay#Tenpay
// 加入選購商品資料。
array_push($oPayment->Send['Items'],
array(
'Name' => "結算",
'Price' => (int)$data['amt'],
'Currency' => "元",
'Quantity' => (int) "1",
'URL' => "http://www.altob.com.tw" // 網址是做什麼用的 ?
)
);
/* 產生訂單 */
$oPayment->CheckOut();
/* 產生訂單 Html Code 的方法 */
$szHtml = $oPayment->CheckOutString();
default:
$sMsg = 'status != 100';
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
echo $sMsg;
}
}
}catch (Exception $e){
// 例外錯誤處理。
$sMsg = $e->getMessage();
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
echo $sMsg;
}
}
// 付款完成 (tx_bill)
public function tx_bill_finished()
{
ob_end_clean();
ignore_user_abort();
ob_start();
try{
$oPayment = new AllInOne();
/* 服務參數 */
$oPayment->HashKey = ALLPAY_HashKey;
$oPayment->HashIV = ALLPAY_HashIV;
$oPayment->MerchantID = ALLPAY_MerchantID;
/* 取得回傳參數 */
$arFeedback = $oPayment->CheckOutFeedback();
/* 檢核與變更訂單狀態 */
if (sizeof($arFeedback) > 0){
foreach ($arFeedback as $key => $value){
switch ($key){
/* 支付後的回傳的基本參數 */
case "MerchantID": $szMerchantID = $value; break;
case "MerchantTradeNo": $szMerchantTradeNo = $value; break;
case "PaymentDate": $szPaymentDate = $value; break;
case "PaymentType": $szPaymentType = $value; break;
case "PaymentTypeChargeFee": $szPaymentTypeChargeFee = $value; break;
case "RtnCode": $szRtnCode = $value; break;
case "RtnMsg": $szRtnMsg = $value; break;
case "SimulatePaid": $szSimulatePaid = $value; break;
case "TradeAmt": $szTradeAmt = $value; break;
case "TradeDate": $szTradeDate = $value; break;
case "TradeNo": $szTradeNo = $value; break;
default: break;
}
}
// 一律記錄log。
$data = array(
'merchant_id' => $szMerchantID,
'merchant_trade_no' => $szMerchantTradeNo,
'payment_date' => $szPaymentDate,
'payment_type' => $szPaymentType,
'payment_type_charge_fee' => $szPaymentTypeChargeFee,
'rtn_code' => $szRtnCode,
'rtn_msg' => $szRtnMsg,
'simulate_paid' => $szSimulatePaid,
'trade_amt' => $szTradeAmt,
'trade_date' => $szTradeDate,
'trade_no' => $szTradeNo
);
$this->allpay_payment_model->create_allpay_feedback_log($data);
print '1|OK'; //先回傳ok
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
// 此筆交易為成功
if($szRtnCode == '1')
{
$data = $this->payment_model->get_tx_bill($szMerchantTradeNo);
if (! empty($data))
{
$order_no = $data['order_no'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
// 印發票流程
if($szTradeAmt == $amt){
// 先記錄
$this->payment_model->transfer_money_done($order_no);
if(! empty($data["service_url"])){
file_get_contents($data["service_url"]."/{$order_no}"); // 執行指定的結帳呼叫
}else{
// 找不到付款成功服務位址
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.'service_url not found..');
}
}else{
// 錢沒對上
$this->payment_model->transfer_money_done_with_amt_error($szMerchantTradeNo);
}
break;
default:
// 對方多傳一次時??
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.'tx_bill.status != 100');
}
}else{
// 我們自己找不到記錄時??
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.'tx_bill NOT FOUND !!');
}
}
}else{
print '0|Fail';
}
}catch (Exception $e){
// 例外錯誤處理。
print '0|' . $e->getMessage();
}
exit();
}
// 付款完成 (tx_bill_ats)
public function tx_bill_ats_finished()
{
ob_end_clean();
ignore_user_abort();
ob_start();
try{
$oPayment = new AllInOne();
/* 服務參數 */
$oPayment->HashKey = ALLPAY_HashKey;
$oPayment->HashIV = ALLPAY_HashIV;
$oPayment->MerchantID = ALLPAY_MerchantID;
/* 取得回傳參數 */
$arFeedback = $oPayment->CheckOutFeedback();
/* 檢核與變更訂單狀態 */
if (sizeof($arFeedback) > 0){
foreach ($arFeedback as $key => $value){
switch ($key){
/* 支付後的回傳的基本參數 */
case "MerchantID": $szMerchantID = $value; break;
case "MerchantTradeNo": $szMerchantTradeNo = $value; break;
case "PaymentDate": $szPaymentDate = $value; break;
case "PaymentType": $szPaymentType = $value; break;
case "PaymentTypeChargeFee": $szPaymentTypeChargeFee = $value; break;
case "RtnCode": $szRtnCode = $value; break;
case "RtnMsg": $szRtnMsg = $value; break;
case "SimulatePaid": $szSimulatePaid = $value; break;
case "TradeAmt": $szTradeAmt = $value; break;
case "TradeDate": $szTradeDate = $value; break;
case "TradeNo": $szTradeNo = $value; break;
default: break;
}
}
// 一律記錄log。
$data = array(
'merchant_id' => $szMerchantID,
'merchant_trade_no' => $szMerchantTradeNo,
'payment_date' => $szPaymentDate,
'payment_type' => $szPaymentType,
'payment_type_charge_fee' => $szPaymentTypeChargeFee,
'rtn_code' => $szRtnCode,
'rtn_msg' => $szRtnMsg,
'simulate_paid' => $szSimulatePaid,
'trade_amt' => $szTradeAmt,
'trade_date' => $szTradeDate,
'trade_no' => $szTradeNo
);
$this->allpay_payment_model->create_allpay_feedback_log($data);
print '1|OK'; //先回傳ok
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
// 此筆交易為成功
if($szRtnCode == '1')
{
$data = $this->payment_ats_model->get_tx_bill($szMerchantTradeNo);
if (! empty($data))
{
$order_no = $data['order_no'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
// 印發票流程
if($szTradeAmt == $amt){
// 先記錄
$this->payment_ats_model->transfer_money_done($order_no);
if(! empty($data["service_url"])){
file_get_contents($data["service_url"]."/{$order_no}"); // 執行指定的結帳呼叫
}else{
// 找不到付款成功服務位址
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.' service_url not found..');
}
}else{
// 錢沒對上
$this->payment_ats_model->transfer_money_done_with_amt_error($szMerchantTradeNo);
}
break;
default:
// 對方多傳一次時??
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.' status != 100');
}
}else{
// 我們自己找不到記錄時??
trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.' NOT FOUND !!');
}
}
}else{
print '0|Fail';
}
}catch (Exception $e){
// 例外錯誤處理。
print '0|' . $e->getMessage();
}
exit();
}
}

+ 872
- 0
controllers/Carpark.php 파일 보기

@@ -0,0 +1,872 @@
<?php
/*
file: carpark.php 停車管理
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once(MQ_CLASS_FILE);
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'carpark'); // 應用系統名稱
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 Carpark 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->vars['mcache'] = new Memcache;
$this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_PORT) or die ('Could not connect memcache');
// mqtt subscribe
$this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_PORT, uniqid());
//if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); }
$this->vars['mqtt']->connect();
$this->load->model('carpark_model');
$this->carpark_model->init($this->vars);
// 微調剩餘車位數
$this->load->model('sync_data_model');
$this->sync_data_model->init($this->vars);
// 產生 excel 報表
$this->load->model('excel_model');
$this->excel_model->init($this->vars);
// [START] 2016/06/03 登入
$this->load->model('user_model');
// load library
$this->load->library(array('form_validation','session'));
// load helpers
$this->load->helper(array('form'));
// ajax code
define('RESULT_SUCCESS', 'ok');
define('RESULT_FORM_VALIDATION_FAIL', '-1');
define('RESULE_FAIL', 'gg');
// [START] 2016/06/03 登入
}
// 發生錯誤時集中在此處理
public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
// ex: car_err://message....
$log_msg = explode('://', $errstr);
if (count($log_msg) > 1)
{
$log_file = LOG_PATH.$log_msg[0];
$str = date('H:i:s')."|{$log_msg[1]}|{$errfile}|{$errline}|{$errno}\n";
}
else
{
$log_file = LOG_PATH.APP_NAME;
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
}
//$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
error_log($str, 3, $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');
// 20170921
header("cache-Control: no-store, no-cache, must-revalidate");
header("cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
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);
}
}
// ------------------------------------------------
//
// 接收端 (START)
//
// ------------------------------------------------
// [設定檔] 取得設定
public function station_setting_query()
{
$reload = $this->input->post('reload', true);
if(isset($reload) && $reload > 0)
{
$station_setting = $this->sync_data_model->station_setting_query(true); // 強制重新載入
trigger_error(__FUNCTION__ . '..station_setting: '. print_r($station_setting, true));
if(!$station_setting)
{
echo json_encode('fail', JSON_UNESCAPED_UNICODE);
exit; // 中斷
}
$info = array('station_no_arr' => $station_setting['station_no']);
usleep(300000); // 0.3 sec delay
// 費率資料同步
$result = $this->sync_data_model->sync_price_plan($info);
trigger_error(__FUNCTION__ . '..sync_price_plan: '. $result);
usleep(300000); // 0.3 sec delay
// 會員資料同步
$result = $this->sync_data_model->sync_members($info);
trigger_error(__FUNCTION__ . '..sync_members: '. $result);
usleep(300000); // 0.3 sec delay
// 在席資料同步
$result = $this->sync_data_model->sync_pks_groups_reload($station_setting);
trigger_error(__FUNCTION__ . '..sync_pks_groups_reload: '. $result);
}
else
{
$station_setting = $this->sync_data_model->station_setting_query(false);
if(!$station_setting)
{
echo json_encode('fail', JSON_UNESCAPED_UNICODE);
exit; // 中斷
}
}
echo json_encode($station_setting, JSON_UNESCAPED_UNICODE);
}
// [排程 or 強制] 同步場站資訊
public function sync_station_data()
{
trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
$switch_lpr_arr = array(); // 換車牌
$meta = $this->input->post('meta', true);
if(!empty($meta))
{
trigger_error( __FUNCTION__ . '..meta_arr..' . $meta);
$meta_arr = explode('@@@', $meta);
foreach($meta_arr as $raw)
{
if(empty($raw))
continue;
$data = json_decode($raw, true);
if($data['key'] == 'switch_lpr')
{
array_push($switch_lpr_arr, $data['value']);
}
}
}
// 0. 取得場站設定
$station_setting = $this->sync_data_model->station_setting_query(false);
trigger_error(__FUNCTION__ . '..station_setting: '. print_r($station_setting, true));
$station_no_arr = array('station_no_arr' => $station_setting['station_no']);
// 1. 月租系統
$result = $this->sync_data_model->sync_members($station_no_arr);
trigger_error(__FUNCTION__ . '..sync_members: '. $result);
// 2. 同步車牌更換
if(!empty($switch_lpr_arr))
{
$this->sync_data_model->sync_switch_lpr($switch_lpr_arr);
}
}
// [API] 取得最新未結清
public function get_last_unbalanced_cario()
{
trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
$lpr = $this->input->post('lpr', true);
$station_no = $this->input->post('station_no', true);
$c_s = $this->input->post('c_s', true);
// 確認正確性
if(empty($c_s) || $c_s != md5('altob'.$lpr.'botla'.$station_no))
{
trigger_error(__FUNCTION__ . "..{$lpr}|".$station_no."|{$c_s}..check fail..");
echo 'fail';
exit;
}
$data = $this->carpark_model->get_last_unbalanced_cario($lpr, $station_no);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// [API] 更新未結清 (行動支付)
public function sync_m2payed()
{
trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
$lpr = $this->input->post('lpr', true);
$amt = $this->input->post('amt', true);
$station_no = $this->input->post('station_no', true);
$cario_no = $this->input->post('cario_no', true);
$c_s = $this->input->post('c_s', true);
// 確認正確性
if(empty($c_s) || $c_s != md5($lpr.$amt.'altob'.$station_no.'botla'.$cario_no))
{
trigger_error(__FUNCTION__ . "..{$lpr}|{$amt}|{$station_no}|{$cario_no}|{$c_s}..check fail..");
echo 'fail';
exit;
}
// 臨停繳費
$this->load->model('carpayment_model');
echo $this->carpayment_model->p2payed(array('seqno' => $cario_no, 'lpr' => $lpr, 'amt' => $amt), true);
exit;
//echo 'ok';
}
// 驗証 IP
function is_ip_valid()
{
$client_ip = $this->my_ip();
if(!in_array($client_ip, array('61.219.172.11', '61.219.172.82')))
{
trigger_error('..block..from:'.$client_ip.'..unknown network..');
return false;
}
return true;
}
// 取得 IP
function my_ip()
{
if (getenv('HTTP_X_FORWARDED_FOR'))
{
$ip = getenv('HTTP_X_FORWARDED_FOR');
}
elseif (getenv('HTTP_X_REAL_IP'))
{
$ip = getenv('HTTP_X_REAL_IP');
}
else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
// 同步 (由排程呼叫)
public function sync_minutely()
{
$this->sync_data_model->sync_pks_groups(); // 同步在席現況
}
// 20170816 手動新增入場資料
public function gen_carin()
{
trigger_error(__FUNCTION__ . '..from..'. $this->my_ip() .'..network..'); // IP 會浮動?
$lpr = $this->input->post('lpr', true);
$station_no = $this->input->post('station_no', true);
$c_s = $this->input->post('c_s', true);
// 確認正確性
if(empty($c_s) || $c_s != md5($lpr.'altob'.$station_no.'botla'. __FUNCTION__ ))
{
trigger_error(__FUNCTION__ . "..{$lpr}|{$station_no}|{$c_s}..check fail..");
echo 'fail';
exit;
}
$parms = array(
'sno' => $station_no,
'lpr' => $lpr,
'etag' => 'NONE',
'io' => 'CI',
'ivsno' => 0
);
$this->carpark_model->gen_carin($parms);
echo 'ok';
}
// ------------------------------------------------
//
// 接收端 (END)
//
// ------------------------------------------------
// [START] 2016/06/03 登入
public function index()
{
if($this->session->userdata('logged_in'))
{
$session_data = $this->session->userdata('logged_in');
$data['username'] = $session_data['username'];
$data['type'] = $session_data['type'];
if($data['type'] == 'admin')
{
$this->show_page('admin_page', $data); // 進階管理者介面
}
else
{
$this->show_page('main_page', $data); // 一般
}
}
else
{
//If no session, redirect to login page
//redirect('login', 'refresh');
$this->show_page('login_page');
}
}
// 登入
public function user_login()
{
// form_validation
$this->form_validation->set_rules('login_name', 'login_name', 'trim|required');
$this->form_validation->set_rules('pswd', 'pswd', 'trim|required');
if($this->form_validation->run() == FALSE)
{
return RESULT_FORM_VALIDATION_FAIL;
}
// go model
$data = array
(
'login_name' => $this->input->post('login_name', true),
'pswd' => $this->input->post('pswd', true)
);
$result = $this->user_model->user_login($data);
if($result)
{
$sess_array = array();
foreach($result as $row)
{
$sess_array = array
(
'username' => $row->login_name ,
'type' => $row->user_type
);
$this->session->set_userdata('logged_in', $sess_array);
}
echo RESULT_SUCCESS;
}
else
{
return RESULE_FAIL;
}
}
// 登出
public function user_logout()
{
$this->session->unset_userdata('logged_in');
session_destroy();
return RESULT_SUCCESS;
}
// [END] 2016/06/03 登入
// response http
protected function http_return($return_code, $type)
{
if ($type == 'text') echo $return_code;
else echo json_encode($return_code, JSON_UNESCAPED_UNICODE);
}
// 送出html code
public function get_html()
{
/*
$data = array
(
'company_no' => $this->input->post('company_no', true), // 場站統編
'hq_company_no' => '80682490'
);
$this->load->view(APP_NAME.'/'.$this->input->post('tag_name', true), $data);
*/
$this->load->view(APP_NAME.'/'.$this->input->post('tag_name', true), array());
}
// 讀取cookie內容
protected function get_cookie($cookie_name)
{
if (empty($_COOKIE[$cookie_name])) return array();
return(json_decode($_COOKIE[$cookie_name], true));
}
// 儲存cookie內容
protected function save_cookie($cookie_name, $cookie_info)
{
return setcookie($cookie_name, json_encode($cookie_info, JSON_UNESCAPED_UNICODE), 0, '/');
}
// 月租資料同步
public function rent_sync()
{
$station_no = $this->input->post('station_no', true);
$start_date = $this->input->post('start_date', true);
$end_date = $this->input->post('end_date', true);
// $data = $this->carpark_model->rent_sync($station_no, $start_date, $end_date);
// print_r($data);
}
// 重設剩餘車位數
public function available_set()
{
$data = $this->carpark_model->available_set();
$this->http_return($data, 'json');
}
// 剩餘車位數更新
public function available_update()
{
$station_no = $this->input->get_post('station_no', true);
$data['name'] = $this->input->get_post('st_name', true);
$data['tot_pkg'] = $this->input->get_post('tot_pkg', true);
$data['ava_pkg'] = $this->input->get_post('ava_pkg', true);
$this->http_return($this->carpark_model->available_update($station_no, $data), 'json');
}
// 剩餘車位數查核
public function available_check()
{
$time_point = $this->input->get_post('time_point', true);
$this->http_return($this->carpark_model->available_check($time_point), 'json');
}
// 顯示logs
public function show_logs()
{
$lines = $this->uri->segment(3); // 顯示行數
if (empty($lines)) $lines = 140; // 無行數參數, 預設為40行
if($lines > 1000) $lines = 1000; // 最多 1000行
// 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_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 利用linux指令顯示倒數幾行的logs內容
echo "\n----- " . LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt' . ' -----';
echo '</pre></body></html>';
}
// 顯示logs (cars grep 888)
public function show_888_logs()
{
$lines = $this->uri->segment(3); // 顯示行數
if (empty($lines)) $lines = 1000; // 無行數參數, 預設為1000行
if($lines > 20000) $lines = 20000; // 最多 20000行
$grep_str = ' |grep 888';
$target_str = LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'. $grep_str;
// 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 . ' ' . $target_str); // 利用linux指令顯示倒數幾行的logs內容
echo "\n----- " . $target_str . ' -----';
echo '</pre></body></html>';
}
// 新增月租資料
public function member_add()
{
$data = array
(
'member_no' => $this->input->post('member_no', true),
'station_no' => $this->input->post('station_no', true),
'lpr' => strtoupper($this->input->post('lpr', true)),
'old_lpr' => strtoupper($this->input->post('old_lpr', true)),
'etag' => strtoupper($this->input->post('etag', true)),
'start_date' => $this->input->post('start_date', true),
'end_date' => $this->input->post('end_date', true),
'member_name' => $this->input->post('member_name', true),
'member_nick_name' => $this->input->post('member_name', true),
'mobile_no' => $this->input->post('mobile_no', true),
'member_id' => $this->input->post('member_id', true),
'contract_no' => $this->input->post('contract_no', true),
'amt' => $this->input->post('amt', true),
'tel_h' => $this->input->post('tel_h', true),
'tel_o' => $this->input->post('tel_o', true),
'addr' => $this->input->post('addr', true)
);
trigger_error("add:".print_r($data, true));
if ($data['member_no'] == 0 || $data['old_lpr'] != $data['lpr'])
{
if ($this->carpark_model->check_lpr($data['lpr']) > 0)
{
echo '車牌重複, 請查明再輸入';
exit;
}
}
$this->carpark_model->member_add($data);
echo 'ok';
}
// 查詢月租資料
public function member_query()
{
$data = $this->carpark_model->member_query();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 刪除月租資料
public function member_delete()
{
$member_no = $this->input->post('member_no', true);
$this->carpark_model->member_delete($member_no);
echo 'ok';
}
// 進出場現況表
public function cario_list()
{
$data = $this->carpark_model->cario_list();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 進出場事件即時顯示
public function cario_event()
{
set_time_limit(0);
while(true)
{
}
}
// 顯示圖檔(http://url/carpark.html/pics/lpr_ABY8873_O_0_0_C_20150919210022)
public function pics()
{
// ???
readfile(CAR_PIC.$this->uri->segment(3).'/'.str_replace('/', '', $this->uri->segment(4)).'.jpg');
}
// 汽車開門
public function opendoors()
{
$ivsno = $this->uri->segment(3);
$lanes = array
(
0 => array ('devno' => 0, 'temp' => 0, 'member' => 1), // 1號入口, temp:臨停, member:月租
// 1 => array ('devno' => 0, 'temp' => 2, 'member' => 3), // 2號調撥入口
1 => array ('devno' => 1, 'temp' => 0, 'member' => 1), // 3號調撥出口
2 => array ('devno' => 1, 'temp' => 0, 'member' => 1), // 3號調撥出口
3 => array ('devno' => 1, 'temp' => 2, 'member' => 3) // 4號出口
);
$url = 'http://admin:99999999@192.168.10.53/cgi-bin/basic_setting.cgi?ID=1&';
$member_tag = 'member'; // member:月租會員
// 短路開柵欄
@get_headers("{$url}OUTDEV={$lanes[$ivsno]['devno']}&OUTCH={$lanes[$ivsno][$member_tag]}&OUTSTATUS=1");
usleep(400000); // 暫停0.4秒
// 斷路, 車過關柵欄
@get_headers("{$url}OUTDEV={$lanes[$ivsno]['devno']}&OUTCH={$lanes[$ivsno][$member_tag]}&OUTSTATUS=0");
}
// 調撥車道查詢
public function reversible_lane_query()
{
$max_lane = 4; // 共幾個車道數
for ($idx = 0; $idx < $max_lane; ++$idx)
{
$data[$idx] = file_get_contents("http://192.168.10.51:8090/cgi-bin/switcher.cgi?id={$idx}&action=9");
}
// $data = array(1, 1, 0, 1);
echo json_encode($data);
}
// 車號入場查詢
public function carin_lpr_query()
{
$lpr = $this->uri->segment(3);
$data = $this->carpark_model->carin_lpr_query($lpr);
echo json_encode($data);
}
// 以時間查詢入場資訊
public function carin_time_query()
{
$time_query = $this->input->post('time_query', true);
$minutes_range = $this->input->post('minutes_range', true);
$data = $this->carpark_model->carin_time_query($time_query, $minutes_range);
echo json_encode($data);
}
// 調撥車道設定
public function reversible_lane_set()
{
$lane_no = $this->input->post('lane_no', true);
$actions = $this->input->post('actions', true);
$data = file_get_contents("http://192.168.10.51:8090/cgi-bin/switcher.cgi?id={$lane_no}&action={$actions}");
echo "{$lane_no}|{$actions}|{$data}";
}
// 在席車位檢查未有入場資料清單
public function pks_check_list()
{
$max_rows = $this->uri->segment(3, 100); // 一次讀取筆數, 預設為100筆
$data = $this->carpark_model->pks_check_list($max_rows);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 重設在席查核
public function reset_pks_check()
{
$data = $this->carpark_model->reset_pks_check();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 更正在席車號
public function correct_pks_lpr()
{
$pksno = $this->uri->segment(3, 0); // 車格號碼
$lpr = $this->uri->segment(4, 'NONE'); // 車號
if ($pksno == 0 || $lpr == 'NONE')
{
echo json_encode(array('err' => 1, 'cario_no' => 0), JSON_UNESCAPED_UNICODE);
}
else
{
$data = $this->carpark_model->correct_pks_lpr($pksno, $lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
}
// 入場車號查核在席無資料清單
public function carin_check_list()
{
$max_rows = $this->uri->segment(3, 20); // 一次讀取筆數, 預設為100筆
$data = $this->carpark_model->carin_check_list($max_rows);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 更正入場車號
public function correct_carin_lpr()
{
$cario_no = $this->uri->segment(3, 0); // 車格號碼
$lpr = $this->uri->segment(4, 'NONE'); // 車號
$in_time = urldecode($this->uri->segment(5, '')); // 入場時間
$data = $this->carpark_model->correct_carin_lpr($cario_no, $lpr, $in_time);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 查詢行動支付記錄
public function tx_bill_query()
{
$data = $this->carpark_model->tx_bill_query();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 查詢月租繳款機記錄
public function tx_bill_ats_query()
{
$data = $this->carpark_model->tx_bill_ats_query();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 查詢樓層在席群組
public function pks_group_query()
{
$data = $this->carpark_model->pks_group_query();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 微調剩餘車位數
public function pks_availables_update()
{
$group_id = $this->uri->segment(3); // id
$value = $this->uri->segment(4, 0); // value
$station_no = $this->uri->segment(5); // station_no
$data = $this->sync_data_model->pks_availables_update($group_id, $value, true, $station_no);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 進出場觸發 888 呼叫
/*
public function sync_888()
{
$io = $this->uri->segment(3); // CI, CO, MI, MO
if(empty($io))
{
echo 'io_not_found';
exit;
}
$parms = array('io' => $io, 'etag' => __FUNCTION__, 'lpr' => __FUNCTION__);
echo $this->sync_data_model->sync_888($parms);
exit;
}
*/
public function test()
{
//echo `whoami`;
//echo phpinfo();
}
// 博辰測試用
// http://localhost/carpark.html/test_8068_002/APK7310
public function test_8068_002()
{
$lpr_in = $this->uri->segment(3);
$seqno = '00001';
$cmd = '002';
$token = '000000000';
$lpr = str_pad($lpr_in, 7, '%', STR_PAD_LEFT);
$in_time = '2000/01/01 00:00:00';
$error_str = '';
$service_port = 8068;
$address = "192.168.10.201";
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
$error_str .= "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
} else {
echo "OK.\n";
}
echo "Attempting to connect to '{$address}' on port '{$service_port}'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ({$result}) " . socket_strerror(socket_last_error($socket)) . "\n";
$error_str .= "socket_connect() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "OK.\n";
}
$in = pack('Ca5Ca3Ca9Ca7Ca19', 0x1c, $seqno, 0x1c, $cmd, 0x1c,
$token, 0x1f, $lpr, 0x1f, $in_time
);
$out = '';
echo "socket_write:";
echo "{$in}<br/><br/>";
if(!socket_write($socket, $in, strlen($in)))
{
echo('<p>Write failed</p>');
$error_str .= "socket_write() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n";
}
echo "socket_write..OK..";
echo "<br/><br/>socket_read:";
$out = socket_read($socket, 2048) or die("Could not read server responsen");
//while ($out = socket_read($socket, 2048)) {
// echo $out;
//}
echo "{$out}<br/><br/>";
echo "Closing socket...";
socket_close($socket);
echo "OK.\n\n";
trigger_error($error_str);
exit;
}
// test
public function test_phpexcel()
{
$query_year = 2017;
$query_month = 3;
//$this->excel_model->export_cario_data($query_year, $query_month);
$this->excel_model->export_members();
}
}

+ 238
- 0
controllers/Carpayment.php 파일 보기

@@ -0,0 +1,238 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
file: Carpayment.php 停車計費
http://192.168.10.201/carpayment.html/query_in/ (查詢入場時間)
http://192.168.10.201/carpayment.html/p2payed/
*/
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'carpayment'); // 應用系統名稱
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/carpayment.'); // log file name
class Carpayment extends CI_Controller
{
var $vars = array();
function __construct()
{
// $this->time_start = microtime(true);
parent::__construct();
ignore_user_abort(); // 接受client斷線, 繼續run
$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; // 本站編號
// session_id(ip2long($_SERVER['REMOTE_ADDR'])); // 設定同一device為同一個session
session_start();
// ----- 程式開發階段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->vars['mcache'] = new Memcache;
$this->vars['mcache']->pconnect(MEMCACHE_HOST, MEMCACHE_POST) or die ('Could not connect memcache');
// mqtt subscribe
$this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_PORT, uniqid());
if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); }
*/
$this->load->model('carpayment_model');
$this->carpayment_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代表參考後面的檔名
}
// 顯示logs
public function show_logs()
{
$lines = $this->uri->segment(3); // 顯示行數
if (empty($lines)) $lines = 100; // 無行數參數, 預設為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_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 利用linux指令顯示倒數幾行的logs內容
echo "\n----- " . LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt' . ' -----';
echo '</pre></body></html>';
}
// http://localhost/carpayment.html/p2payed/ (post method)
// 可用$this->input->is_cli_request()判斷是否在cli之下執行
// 博辰aps已付款
public function p2payed()
{
$parms['ticket_no'] = $this->input->post('ticket_no', true);
$parms['lpr'] = trim($this->input->post('lpr', true));
$parms['in_time'] = $this->input->post('in_time', true);
$parms['pay_time'] = $this->input->post('pay_time', true);
$parms['pay_type'] = $this->input->post('pay_type', true);
trigger_error('博辰付款參數:' . print_r($parms, true));
$this->carpayment_model->p2payed($parms);
}
/*
月租繳款完成
http://203.75.167.89/carpayment.html/memberpayed/12345/ABC1234/120/12112/1/2016-01-31/1f3870be274f6c49b3e31a0c6728957f
http://203.75.167.89/carpayment.html/memberpayed/會員號碼/車牌/金額/場站編號/月繳/本期到期日/md5
md5(會員號碼.車牌.金額.場站編號.月繳.本期到期日)
public function memberpayed()
{
$parms['member_no'] = $lines = $this->uri->segment(3);
$parms['lpr'] = $lines = $this->uri->segment(4);
$parms['amt'] = $lines = $this->uri->segment(5);
$parms['station_no'] = $lines = $this->uri->segment(6);
$parms['period_type'] = $lines = $this->uri->segment(7);
$parms['expire_date'] = $lines = $this->uri->segment(8);
$md5 = $this->uri->segment(9);
if (md5($parms['member_no'].$parms['lpr'].$parms['amt'].$parms['station_no'].$parms['seqno'].$parms['period_type'].$parms['expire_date']) === $md5)
{
$this->carpayment_model->memberpayed($parms);
}
}
*/
// 繳費機告知已付款 (new 2016/07/15)
// http://localhost/carpayment.html/ats2payed/車牌/金額/場站編號/序號/MD5
// md5(車牌.金額.場站編號.序號)
public function ats2payed()
{
$result = [];
$parms['lpr'] = $lines = $this->uri->segment(3);
$parms['amt'] = $lines = $this->uri->segment(4);
$parms['station_no'] = $lines = $this->uri->segment(5);
$parms['order_no'] = $lines = $this->uri->segment(6);
$md5 = $this->uri->segment(7);
if (md5($parms['lpr'].$parms['amt'].$parms['station_no'].$parms['order_no']) === $md5)
{
$this->carpayment_model->ats2payed($parms);
}
}
// 行動支付, 手機告知已付款
// http://203.75.167.89/carpayment.html/m2payed/ABC1234/120/12112/12345/1f3870be274f6c49b3e31a0c6728957f
// http://203.75.167.89/carpayment.html/m2payed/車牌/金額/場站編號/序號/MD5
// md5(車牌.金額.場站編號.序號)
public function m2payed()
{
$parms['lpr'] = $lines = $this->uri->segment(3);
$parms['amt'] = $lines = $this->uri->segment(4);
$parms['station_no'] = $lines = $this->uri->segment(5);
$parms['seqno'] = $lines = $this->uri->segment(6);
$md5 = $this->uri->segment(7);
echo $this->carpayment_model->m2payed($parms);
/*
$seqno = !empty($_SESSION['seqno']) ? $_SESSION['seqno'] : 0;
unset($_SESSION['seqno']);
if ($parms['seqno'] != 0 && $parms['seqno'] == $seqno && md5($parms['lpr'].$parms['amt'].$parms['station_no'].$parms['seqno']) === $md5)
{
echo $this->carpayment_model->m2payed($parms);
}
else
echo 'fail';
*/
}
// 查詢入場時間
public function query_in()
{
$lpr = $this->input->post('lpr', true);
$data = $this->carpayment_model->query_in($lpr);
echo json_encode($data);
}
// 查詢入場時間 (fuzzy)
public function query_in_fuzzy()
{
$lpr = $this->input->post('lpr', true);
$data = $this->carpayment_model->query_in_fuzzy($lpr);
echo json_encode($data);
}
// 行動設備查詢入場時間
// http://203.75.167.89/carpayment.html/m2query_in/ABC1234/12112/1f3870be274f6c49b3e31a0c6728957f
// http://203.75.167.89/carpayment.html/m2query_in/車牌/場站編號/MD5
// 回傳0: 失敗, 成功: 12345,60(第一欄位非0數字代表成功, 第二欄位為金額), 此值在付款時必需傳回, 否則視為非法
public function m2query_in()
{
$parms['lpr'] = $lines = $this->uri->segment(3);
$parms['station_no'] = $lines = $this->uri->segment(4);
$md5 = $this->uri->segment(5);
// 驗證md5
if (md5($parms['lpr'].$parms['station_no']) === $md5)
{
$data = $this->carpayment_model->m2query_in($parms);
}
else
{
$data = 0;
}
$_SESSEION['seqno'] = $data;
echo $data;
}
// 測試:回傳 seat_no
// http://192.168.0.199/carpayment.html/test_seat_no/B2/123
public function test_seat_no()
{
$rows['group_id'] = $this->uri->segment(3);
$rows['pksno'] = $this->uri->segment(4);
//echo substr($rows['group_id'], 0, 1);
echo (substr($rows['group_id'], 0, 1) == 'B' ? '-' : '0') . substr($rows['group_id'], 1, 1) . '_' . substr($rows['pksno'], -3);
}
}

+ 234
- 0
controllers/Cars.php 파일 보기

@@ -0,0 +1,234 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
file: cars.php 車輛進出場處理(板車版含感應線圈)
URL:
http://192.168.10.201/cars.html/ipcam/sno/12119/ivsno/0/io/O/type/C/lpr/4750YC/color/NULL/sq/0/ts/1441051995/sq2/0/etag/ABCD123456789/ant/1
javascript/html從server讀取key/value方式
http://61.220.179.128/jsid.i/ip=ip&uniqid=clientid&mqtt_ip=mqtt_ip
例如:
<script src="http://61.220.179.128/jsid.i/ip=ip&uniqid=clientid&mqtt_ip=mqtt_ip"></script>
response:
var ip='66.249.82.183';var clientid='565162cb67dfb';var mqtt_ip='192.168.51.11';
*/
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'cars'); // 應用系統名稱
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/cario.'); // log file name
require_once(MQ_CLASS_FILE);
class Cars 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 == 'ipcam' || $method_name == 'check_lpr_etag')
{
ob_end_clean();
ignore_user_abort();
ob_start();
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
}
else if($method_name == 'opendoor')
{
ob_end_clean();
ignore_user_abort();
ob_start();
echo 'ok';
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; // 本站編號
session_id(ip2long($_SERVER['REMOTE_ADDR'])); // 設定同一device為同一個session
session_start();
// ----- 程式開發階段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->vars['mcache'] = new Memcache;
$this->vars['mcache']->pconnect(MEMCACHE_HOST, MEMCACHE_PORT) or die ('Could not connect memcache');
// mqtt subscribe
$this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_PORT, uniqid());
//if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); }
if(!$this->vars['mqtt']->connect()){ trigger_error('..Could not connect mqtt..go on..'); }
$this->load->model('cars_model');
$this->cars_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代表參考後面的檔名
}
// 顯示logs
public function show_logs()
{
$lines = $this->uri->segment(3); // 顯示行數
if (empty($lines)) $lines = 140; // 無行數參數, 預設為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_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 利用linux指令顯示倒數幾行的logs內容
echo "\n----- " . LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt' . ' -----';
echo '</pre></body></html>';
}
/*
出入口
說明: 與ipcam相同判斷邏輯, 但不做任何資料更改
*/
public function opendoor()
{
$parms = $this->uri->uri_to_assoc(3);
$parms['lpr'] = urldecode($parms['lpr']); // 中文車牌
$this->cars_model->opendoor_lprio($parms);
}
// IVS -> 車號, 影像
/*
鼎高IVS傳送車號及影像檔
http://192.168.10.201/cars.html/ipcam/sno/12119/ivsno/0/io/O/type/C/lpr/4750YC/color/NULL/sq/0/ts/1441051995/sq2/0/etag/ABCD123456789/ant/1
sno: 場站編號(光興國小:12119)
ivsno: ivs編號, 每一支都是獨立編號(序號)
io: i:進場, o:出場
type: C:汽車, H:重機, M:機車
lpr: ABC-1234(車號)
color: red(紅色), 若無請用NULL(4個字)
sq: 序號(參考用)
sq2: 暫不用
etag: eTag ID
ant: eTag
http設定說明:
method: POST
上傳圖檔名英數字, 副檔名為gif/jpg/png均可
上傳圖檔欄位名稱為cars
*/
public function ipcam()
{
$parms = $this->uri->uri_to_assoc(3);
$parms['lpr'] = urldecode($parms['lpr']); // 中文車牌
// 同步並送出一次出入口 888
$this->load->model('sync_data_model');
$this->sync_data_model->init($this->vars);
$this->sync_data_model->sync_888($parms);
$pic_folder = CAR_PIC.$this->vars['date_num'].'/'; // 今日資料夾名(yyyymmdd)
if (!file_exists($pic_folder)) mkdir($pic_folder); // 如果資料夾不存在, 建立日期資料夾
$config['upload_path'] = $pic_folder;
// $config['allowed_types'] = 'gif|jpg|png';
$config['allowed_types'] = '*';
// ex. lpr_1625AB_I_1_152_C_1_2015080526.jpg -> car_交易序號_進出_順序_車號_時間.jpg
$config['file_name'] = "lpr-{$parms['lpr']}-{$parms['io']}-{$parms['ivsno']}-{$parms['sq']}-{$parms['type']}-{$parms['sq2']}-{$this->vars['time_num']}.jpg";
if (!isset($_FILES['cars']))
{
$status = 'error'; // 顯示上傳錯誤
trigger_error('[ERROR] cars not found: ' . print_r($_FILES, true));
}
else
{
$this->load->library('upload', $config);
if(!$this->upload->do_upload('cars')){
$status = 'error'; // 顯示上傳錯誤
trigger_error($this->upload->display_errors());
}
else
{
// 若無錯誤,則上傳檔案
$file = $this->upload->data('cars');
$status = 'ok';
}
}
$parms['obj_type'] = 1; // 車牌類
$parms['curr_time_str'] = $this->vars['date_time']; // 現在時間, 例2015-09-21 15:36:47
$parms['pic_name'] = $config['file_name']; // 圖片檔名
$this->cars_model->lprio($parms); // 測試eTag
}
// 用車牌與eTag, 檢查資料庫
public function check_lpr_etag()
{
$lpr = $this->uri->segment(3);
$etag = $this->uri->segment(4);
$this->cars_model->check_lpr_etag($lpr, $etag);
exit;
}
public function test_now()
{
echo date('Y-m-d H:i:s');
}
public function test_phpinfo()
{
phpinfo();
}
}

+ 218
- 0
controllers/Ctbcbank.php 파일 보기

@@ -0,0 +1,218 @@
<?php
/*
file: Ctbcbank.php 中國信託介接
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Ctbcbank 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->vars['mcache'] = new Memcache;
$this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_PORT) or die ('Could not connect memcache');
// 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', 'ctbcbank'); // 應用系統名稱
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
//$this->load->model('twgc_model');
// $this->parkingquery_model->init($this->vars);
$this->load->model('payment_model'); // 帳單
$this->load->model('ctbcbank_model');// 中國信託金流
$this->load->model('allpay_invoice_model'); // 歐付寶電子發票
define('CTBC_AuthResURL', APP_URL."return_ok/"); // 從收單行端取得授權碼後,要導回的網址,請勿填入特殊字元@、#、%、?、&等。
define('MAIN_PAGE', "main_page");
define('RESULT_PAGE', "result_page");
define('ERROR_PAGE', "error_page");
// ----- 回傳訊息 -----
define('RESULT_CODE_OK', "OK");
define('RESULT_CODE_UNKNOWN_ERROR', "-99");
define('RESULT_MSG_UNKNOWN_ERROR', "發生未預期錯誤");
// ----- 回傳訊息 (END) -----
}
// 發生錯誤時集中在此處理
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代表參考後面的檔名
//echo $str;
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); // http://203.75.167.89/ctbcbank.html
}
// 查車付款 - 1.查車拿帳單
public function payment_lpr()
{
$payment_lpr = $this->input->post('payment_lpr', true);
$data = $this->payment_model->create_cario_bill($payment_lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 查車付款 - 2.確定繳交帳單
public function transfer_money()
{
$order_no = strtoupper($this->uri->segment(3)); // 交易序號
$invoice_receiver = urldecode($this->uri->segment(4)); // 載具編號 (可有可無)
$company_no = urldecode($this->uri->segment(5)); // 載具編號 (可有可無)
$email_base64 = $this->uri->segment(6); // 電子信箱
$mobile = $this->uri->segment(7); // 手機號碼
// decode email
if(strlen($email_base64) > 0){
$email = base64_decode($email_base64.'='); // base64字串尾端的'='還原
}else{
$email = email_base64;
}
$data = $this->payment_model->pay_bill($order_no, $invoice_receiver, $company_no, $email, $mobile); // 繳交帳單
if (!empty($data)){
$this->ctbcbank_model->transfer_money_ctbc($data, CTBC_AuthResURL); // 中國信託
}
}
// C.4 收單行端取得授權碼後,要導回的網址 (call by CTBC)
public function return_ok()
{
/**
=======ALL_REQUEST======
URLResEnc: AF2100C51A9E844A1E820B953EA512BE49286403253FF9373474F6AE4A5877B084DD4D9B20F03AF0F34DB3D42A9C583938FE5DC1B60C53384864D9581EE997F92552A2F516B04F2FB2FE3E5C10D61CE84C5B63B87379F1048E16AC430AE94989724D8B0087734F73BF40CE904A05D555F526E5A93462C42931A0A7EC1E6AFF8BC39E641A8F5EE8882BD5B02F838BC217A87533AB9FE98CE1DD558B3CC345FC77D06C1783067F75DF94C58B55A826CD33B32355439BF3C9F17A4596138942B4457B66EB8FA09749C246D5B91799FB3942EC90138033272D89861B8698398FF4F3010628C0D11C7D88FB7A5F85CC59717D9F8D5CADBA5A1231E0396AE344B1DA139BA84F9D477E53A73A376BFCC92B52619E3B396BB28ABE7C4CEE3D3ED2CA1BEEF466F2D645C5CBF1C678C5747BA2A048F2F0FC2B86CAE379DE7A7F144D07C31A
merID: 10063
----------------------------END
*/
// 取得回傳資訊
foreach ($_REQUEST as $key => $value) {
switch ($key){
case "URLResEnc": $resenc = $value; break;
case "merID": $merid = $value; break;
}
}
if(! empty($resenc)){
$return_data = $this->ctbcbank_model->ctbcbank_return_handler($resenc, $merid);
$ctbc_lidm = $return_data['lidm'];
$ctbc_authamt = $return_data['authamt'];
$ctbc_status = $return_data['status'];
if($ctbc_status != 0){
// 金流處理失敗
trigger_error(__FUNCTION__.', ctbc_status GG ..lidm=>' . $ctbc_lidm);
}else if(! empty($ctbc_lidm)) {
$data = $this->payment_model->get_tx_bill($ctbc_lidm);
if (! empty($data)) {
$order_no = $data['order_no'];
$lpr = $data['lpr'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
// 印發票流程
if($ctbc_authamt == $amt){
// 先記錄
$this->payment_model->transfer_money_done($order_no);
// 開立歐付寶電子發票
//$this->allpay_invoice_model->invoice_issue_for_product_bill($order_no, $amt);
// 交易成功
$this->show_page(RESULT_PAGE);
return;
}else{
// 錢沒對上
$this->payment_model->transfer_money_done_with_error_2($order_no);
}
break;
default:
// 對方多傳一次時??
trigger_error(__FUNCTION__.', order_no=>' . $order_no.'<br>'.'status != 100');
}
}else{
// 我們自己找不到記錄時??
trigger_error(__FUNCTION__.', order_no=>' . $order_no.'<br>'.' NOT FOUND !!');
}
}else{
// 回傳沒有資料 lidm
trigger_error(__FUNCTION__.', ERROR ..lidm=>' . $ctbc_lidm);
}
}else{
// 回傳沒有資料 resenc
trigger_error(__FUNCTION__.', ERROR ..resenc=>' . $resenc);
}
// 交易失敗
$this->show_page(ERROR_PAGE);
}
}

+ 163
- 0
controllers/Parkingquery.php 파일 보기

@@ -0,0 +1,163 @@
<?php
/*
file: carpark.php 停車管理
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// require_once(MQ_CLASS_FILE);
class Parkingquery 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->vars['mcache'] = new Memcache;
$this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_PORT) or die ('Could not connect memcache');
// 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', 'parkingquery'); // 應用系統名稱
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
$this->load->model('parkingquery_model');
$this->load->model('security_model'); // 鎖車
// $this->parkingquery_model->init($this->vars);
}
// 發生錯誤時集中在此處理
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);
}
}
// response http
protected function http_return($return_code, $type)
{
if ($type == 'text') echo $return_code;
else echo json_encode($return_code, JSON_UNESCAPED_UNICODE);
}
// 查詢各樓層剩餘車位
// http://203.75.167.89/parkingquery.html/check_space/12345
public function check_space()
{
$seqno = $this->uri->segment(3);
$data = $this->parkingquery_model->check_space($seqno);
$data['result']['num'] = $seqno;
$data['result_code'] = 'OK';
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 停車位置查詢(板橋好停車)
// http://203.75.167.89/parkingquery.html/check_location/ABC1234
public function check_location()
{
$lpr = $this->uri->segment(3);
$data = $this->parkingquery_model->check_location($lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 空車位導引
// http://203.75.167.89/parkingquery.html/get_valid_seat
public function get_valid_seat()
{
$pksno = $this->uri->segment(3, 0); // 從某一個車位開始, 若無則設0
$data = $this->parkingquery_model->get_valid_seat($pksno);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 緊急求救
// http://203.75.167.89/parkingquery.html/send_sos/B2/111/123
public function send_sos()
{
$floor = $this->uri->segment(3);
$x = $this->uri->segment(4);
$y = $this->uri->segment(5);
get_headers("http://localhost/sos/set_sos.php?floor={$floor}&x={$x}&y={$y}");
$data = $this->parkingquery_model->send_sos($floor, $x, $y);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 防盜鎖車
// http://203.75.167.89/parkingquery.html/security_action/ABC1234/pswd/2
public function security_action()
{
$lpr = $this->uri->segment(3);
$pswd = $this->uri->segment(4);
$action = $this->uri->segment(5);
$data = $this->security_model->security_action($lpr, $pswd, $action);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 警急求救地圖
public function floor_map()
{
$this->show_page("floor_map");
}
}

+ 204
- 0
controllers/Payment.php 파일 보기

@@ -0,0 +1,204 @@
<?php
/*
file: Payment.php 付費系統
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Payment 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
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'payment'); // 應用系統名稱
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
$this->load->model('payment_model'); // 臨停繳費
$this->load->model('allpay_invoice_model'); // 歐付寶電子發票
$this->load->model('security_model'); // 鎖車
define('MAIN_PAGE', "main_page");
define('RESULT_PAGE', "result_page");
// ----- 行動支付, 手機告知已付款 -----
define('ALTOB_M2PAYED', "http://localhost/carpayment.html/m2payed");
// ----- 行動支付, 手機告知已付款 (end) -----
// ----- 歐付寶金流 -----
define('ALLPAY_PAYMENT_TX_BILL', SERVER_URL."allpay_payment.html/transfer_money_tx_bill"); // 歐付寶付款系統連結
define('ALLPAY_ClientBackURL', APP_URL."client_back/"); // 您要歐付寶返回按鈕導向的瀏覽器端網址";
define('ALLPAY_OrderResultURL', APP_URL."order_result/"); // 您要收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來;
define('ALLPAY_AltobServiceURL', APP_URL."payment_completed_handler/"); // 付款完成後被通知的位址
// ----- 歐付寶金流 (end) -----
}
// 發生錯誤時集中在此處理
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);
}
// 查車付款 - 1.查車拿帳單
public function payment_lpr()
{
$payment_lpr = $this->input->post('payment_lpr', true);
$data = $this->payment_model->create_cario_bill($payment_lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 查車付款 - 2.確定繳交帳單
public function transfer_money()
{
$order_no = strtoupper($this->uri->segment(3)); // 交易序號
$invoice_receiver = urldecode($this->uri->segment(4)); // 載具編號 (可有可無)
$company_no = urldecode($this->uri->segment(5)); // 公司統編 (可有可無)
$email_base64 = $this->uri->segment(6); // 電子信箱
$mobile = $this->uri->segment(7); // 手機號碼
// decode email
if(strlen($email_base64) > 0){
$email = base64_decode($email_base64.'='); // base64字串尾端的'='還原
}else{
$email = email_base64;
}
$this->payment_model-> // 開始進行繳交帳單
pay_bill($order_no, $invoice_receiver, $company_no, $email, $mobile,
ALLPAY_ClientBackURL,
ALLPAY_OrderResultURL,
ALLPAY_AltobServiceURL,
50); // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址
// 轉址歐付寶付款系統
echo file_get_contents(ALLPAY_PAYMENT_TX_BILL."/{$order_no}");
}
// L.1 付款完成 (限制存取)
public function payment_completed_handler()
{
$order_no = $this->uri->segment(3); // 交易序號
$data = $this->payment_model->get_tx_bill($order_no);
if (! empty($data))
{
$cario_no = $data['cario_no'];
$station_no = $data['station_no'];
$lpr = $data['lpr'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 1: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 111:產品已領取
// 開立歐付寶電子發票
$this->allpay_invoice_model->invoice_issue_for_tx_bill($order_no, $amt);
// 記錄為已領取
$this->payment_model->transfer_money_done_and_finished($order_no);
// 行動支付, 手機告知已付款
// http://203.75.167.89/carpayment.html/m2payed/車牌/金額/場站編號/序號/MD5
// md5(車牌.金額.場站編號.序號)
$md5 = md5($lpr.$amt.$station_no.$cario_no);
file_get_contents(ALTOB_M2PAYED."/{$lpr}/{$amt}/{$station_no}/{$cario_no}/{$md5}");
default:
// 尚未結帳完成, 或是已領取
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no.'<br>'.'tx_bill.status != 1');
}
}
}
// 歐付寶返回按鈕導向的瀏覽器端網址
public function client_back()
{
$this->show_page(MAIN_PAGE);
}
// 收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來
public function order_result()
{
$this->show_page(RESULT_PAGE);
}
// 其它功能 1: 更改會員密碼
public function change_pswd()
{
$lpr = $this->input->post('lpr', true);
$new_pswd = $this->input->post('new_pswd', true);
$data = $this->security_model->change_pswd($lpr, $new_pswd);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 其它功能 2: 防盜鎖車
public function security_action()
{
$lpr = $this->uri->segment(3);
$pswd = $this->uri->segment(4);
$action = $this->uri->segment(5);
$data = $this->security_model->security_action($lpr, $pswd, $action);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// show image
public function pics()
{
readfile(PKS_PIC. $this->uri->segment(3).'.jpg');
}
}

+ 198
- 0
controllers/Payment_ats.php 파일 보기

@@ -0,0 +1,198 @@
<?php
/*
file: Payment_ats.php 繳費機
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Payment_ats 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
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'payment_ats'); // 應用系統名稱
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
$this->load->model('payment_ats_model'); // 臨停繳費
$this->load->model('allpay_invoice_model'); // 歐付寶電子發票
define('MAIN_PAGE', "main_page");
define('RESULT_PAGE', "result_page");
// ----- 行動支付, 繳費機告知已付款 -----
define('ALTOB_ATS2PAYED', "http://localhost/carpayment.html/ats2payed");
// ----- 行動支付, 繳費機告知已付款 (end) -----
// ----- 歐付寶金流 -----
define('ALLPAY_PAYMENT_TX_BILL_ATS', SERVER_URL."allpay_payment.html/transfer_money_tx_bill_ats"); // 歐付寶付款系統連結
define('ALLPAY_ClientBackURL', APP_URL."client_back/"); // 您要歐付寶返回按鈕導向的瀏覽器端網址";
define('ALLPAY_OrderResultURL', APP_URL."order_result/"); // 您要收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來;
define('ALLPAY_AltobServiceURL', APP_URL."payment_completed_handler/"); // 付款完成後被通知的位址
// ----- 歐付寶金流 (end) -----
}
// 發生錯誤時集中在此處理
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);
}
// 查車付款 - 1.查車拿帳單
public function payment_lpr()
{
$payment_lpr = $this->input->post('payment_lpr', true);
$data = $this->payment_ats_model->create_member_bill($payment_lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 查車付款 - 2.確定繳交帳單
public function transfer_money()
{
$order_no = strtoupper($this->uri->segment(3)); // 交易序號
$invoice_receiver = urldecode($this->uri->segment(4)); // 載具編號 (可有可無)
$company_no = urldecode($this->uri->segment(5)); // 公司統編 (可有可無)
$email_base64 = $this->uri->segment(6); // 電子信箱
$mobile = $this->uri->segment(7); // 手機號碼
// decode email
if(strlen($email_base64) > 0){
$email = base64_decode($email_base64.'='); // base64字串尾端的'='還原
}else{
$email = email_base64;
}
$this->payment_ats_model-> // 開始進行繳交帳單
pay_bill($order_no, $invoice_receiver, $company_no, $email, $mobile,
ALLPAY_ClientBackURL,
ALLPAY_OrderResultURL,
ALLPAY_AltobServiceURL,
50); // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址
// 轉址歐付寶付款系統
echo file_get_contents(ALLPAY_PAYMENT_TX_BILL_ATS."/{$order_no}");
}
// L.1 付款完成 (限制存取)
public function payment_completed_handler()
{
$order_no = $this->uri->segment(3); // 交易序號
$data = $this->payment_ats_model->get_tx_bill($order_no);
if (! empty($data))
{
$order_no = $data['order_no'];
$station_no = $data['station_no'];
$lpr = $data['lpr'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 1: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 111:產品已領取
// 開立歐付寶電子發票
$this->allpay_invoice_model->invoice_issue_for_tx_bill_ats($order_no, $amt);
// 記錄為已領取
$this->payment_ats_model->transfer_money_done_and_finished($order_no);
// 繳費機告知已付款
// http://localhost/carpayment.html/ats2payed/車牌/金額/場站編號/序號/MD5
// md5(車牌.金額.場站編號.序號)
$md5 = md5($lpr.$amt.$station_no.$order_no);
file_get_contents(ALTOB_ATS2PAYED."/{$lpr}/{$amt}/{$station_no}/{$order_no}/{$md5}");
default:
// 尚未結帳完成, 或是已領取
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no.'<br>'.' status != 1');
}
}
}
// 歐付寶返回按鈕導向的瀏覽器端網址
public function client_back()
{
$this->show_page(MAIN_PAGE);
}
// 收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來
public function order_result()
{
$this->show_page(RESULT_PAGE);
}
// 其它功能 1: 更改會員密碼
public function change_pswd()
{
$lpr = $this->input->post('lpr', true);
$new_pswd = $this->input->post('new_pswd', true);
$data = $this->security_model->change_pswd($lpr, $new_pswd);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 其它功能 2: 防盜鎖車
public function security_action()
{
$lpr = $this->uri->segment(3);
$pswd = $this->uri->segment(4);
$action = $this->uri->segment(5);
$data = $this->security_model->security_action($lpr, $pswd, $action);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
}

+ 268
- 0
controllers/Pks.php 파일 보기

@@ -0,0 +1,268 @@
<?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");
}
}

+ 242
- 0
controllers/Qcar.php 파일 보기

@@ -0,0 +1,242 @@
<?php
/*
file: qcar.php 查車系統
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Qcar 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->vars['mcache'] = new Memcache;
$this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_POST) or die ('Could not connect memcache');
// mqtt subscribe
$this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_POST, 'cario');
if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); }
*/
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'qcar'); // 應用系統名稱
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
$this->load->model('qcar_model');
$this->load->model('payment_ats_model'); // 繳費
$this->load->model('allpay_invoice_model'); // 歐付寶電子發票
define('MAIN_PAGE', "main_page");
define('RESULT_PAGE', "result_page");
// ----- 行動支付, 繳費機告知已付款 -----
define('ALTOB_ATS2PAYED', "http://localhost/carpayment.html/ats2payed");
// ----- 行動支付, 繳費機告知已付款 (end) -----
// ----- 歐付寶金流 -----
define('ALLPAY_PAYMENT_TX_BILL_ATS', SERVER_URL."allpay_payment.html/transfer_money_tx_bill_ats"); // 歐付寶付款系統連結
define('ALLPAY_ClientBackURL', APP_URL."client_back/"); // 您要歐付寶返回按鈕導向的瀏覽器端網址";
define('ALLPAY_OrderResultURL', APP_URL."order_result/"); // 您要收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來;
define('ALLPAY_AltobServiceURL', APP_URL."payment_completed_handler/"); // 付款完成後被通知的位址
// ----- 歐付寶金流 (end) -----
}
// 發生錯誤時集中在此處理
public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
// ex: car_err://message....
//$log_msg = explode('://', $errstr);
/*
if (count($log_msg) > 1)
{
$log_file = LOG_PATH.$log_msg[0];
$str = date('H:i:s')."|{$log_msg[1]}|{$errfile}|{$errline}|{$errno}\n";
}
else
{
$log_file = LOG_PATH.APP_NAME;
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
}
*/
$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>';
}
// 付款 - 1.繳月租
public function payment_lpr()
{
$payment_lpr = $this->input->post('payment_lpr', true);
$data = $this->payment_ats_model->create_member_bill($payment_lpr);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 付款 - 2.確定繳費
public function transfer_money()
{
$order_no = strtoupper($this->uri->segment(3)); // 交易序號
$invoice_receiver = urldecode($this->uri->segment(4)); // 載具編號 (可有可無)
$company_no = urldecode($this->uri->segment(5)); // 公司統編 (可有可無)
$email_base64 = $this->uri->segment(6); // 電子信箱
$mobile = $this->uri->segment(7); // 手機號碼
// decode email
if(strlen($email_base64) > 0){
$email = base64_decode($email_base64.'='); // base64字串尾端的'='還原
}else{
$email = email_base64;
}
$this->payment_ats_model-> // 開始進行繳交帳單
pay_bill($order_no, $invoice_receiver, $company_no, $email, $mobile,
ALLPAY_ClientBackURL,
ALLPAY_OrderResultURL,
ALLPAY_AltobServiceURL,
52); // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址
// 轉址歐付寶付款系統
echo file_get_contents(ALLPAY_PAYMENT_TX_BILL_ATS."/{$order_no}");
}
// L.1 付款完成 (限制存取)
public function payment_completed_handler()
{
$order_no = $this->uri->segment(3); // 交易序號
$data = $this->payment_ats_model->get_tx_bill($order_no);
if (! empty($data))
{
$order_no = $data['order_no'];
$station_no = $data['station_no'];
$lpr = $data['lpr'];
$amt = $data['amt'];
$status = $data['status'];
switch($status){
case 1: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 111:產品已領取
// 開立歐付寶電子發票
$this->allpay_invoice_model->invoice_issue_for_tx_bill_ats($order_no, $amt);
// 記錄為已領取
$this->payment_ats_model->transfer_money_done_and_finished($order_no);
// 繳費機告知已付款
// http://localhost/carpayment.html/ats2payed/車牌/金額/場站編號/序號/MD5
// md5(車牌.金額.場站編號.序號)
$md5 = md5($lpr.$amt.$station_no.$order_no);
file_get_contents(ALTOB_ATS2PAYED."/{$lpr}/{$amt}/{$station_no}/{$order_no}/{$md5}");
default:
// 尚未結帳完成, 或是已領取
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no.'<br>'.' status != 1');
}
}
}
// 歐付寶返回按鈕導向的瀏覽器端網址
public function client_back()
{
$this->show_page(MAIN_PAGE);
}
// 收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來
public function order_result()
{
$this->show_page(RESULT_PAGE);
}
// 車位查詢
public function q_pks()
{
$lpr = $this->input->post('lpr', true);
$data = $this->qcar_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->qcar_model->q_fuzzy_pks($input);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
}

+ 104
- 0
controllers/Txdata.php 파일 보기

@@ -0,0 +1,104 @@
<?php
/*
file: Txdata.php 交易資訊系統
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Txdata 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->vars['mcache'] = new Memcache;
$this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_PORT) or die ('Could not connect memcache');
// 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', 'txdata'); // 應用系統名稱
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
$this->load->model('txdata_model');
// $this->parkingquery_model->init($this->vars);
}
// 發生錯誤時集中在此處理
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);
}
}
// 取得場站費率設定
// http://203.75.167.89/txdata.html/get_price_plan/12112/0
public function get_price_plan()
{
$station_no = $this->uri->segment(3);
$tx_type = $this->uri->segment(4);
$data = $this->txdata_model->get_price_plan($station_no, $tx_type);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 取得特殊日期設定
// http://203.75.167.89/txdata.html/get_date_plan/12345678/23456789
public function get_date_plan()
{
$inTime = $this->uri->segment(3);
$balanceTime = $this->uri->segment(4);
$data = $this->txdata_model->get_date_plan($inTime, $balanceTime);
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
}

+ 353
- 0
controllers/Vip.php 파일 보기

@@ -0,0 +1,353 @@
<?php
/*
file: vip.php 交通局VIP管理系統
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once(MQ_CLASS_FILE);
session_start(); //we need to call PHP's session object to access it through CI
class Vip 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->vars['mcache'] = new Memcache;
$this->vars['mcache']->connect(MEMCACHE_HOST, MEMCACHE_POST) or die ('Could not connect memcache');
// mqtt subscribe
$this->vars['mqtt'] = new phpMQTT(MQ_HOST, MQ_POST, 'cario');
if(!$this->vars['mqtt']->connect()){ die ('Could not connect mqtt'); }
**/
// ----- 定義常數(路徑, cache秒數) -----
define('APP_VERSION', '100'); // 版本號
define('MAX_AGE', 604800); // cache秒數, 此定義1個月
define('APP_NAME', 'vip'); // 應用系統名稱
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
$this->load->model('vip_model');
$this->vip_model->init($this->vars);
// load library
$this->load->library(array('form_validation','session'));
// load helpers
$this->load->helper(array('form'));
// ajax code
define('RESULT_SUCCESS', 'ok');
define('RESULT_FORM_VALIDATION_FAIL', '-1');
define('RESULE_FAIL', 'gg');
}
// 發生錯誤時集中在此處理
public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
// ex: car_err://message....
//$log_msg = explode('://', $errstr);
/*
if (count($log_msg) > 1)
{
$log_file = LOG_PATH.$log_msg[0];
$str = date('H:i:s')."|{$log_msg[1]}|{$errfile}|{$errline}|{$errno}\n";
}
else
{
$log_file = LOG_PATH.APP_NAME;
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
}
*/
$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()
{
if($this->session->userdata('logged_in'))
{
$session_data = $this->session->userdata('logged_in');
$data['username'] = $session_data['username'];
$data['type'] = $session_data['type'];
if($data['type'] == 'ma')
{
$this->show_page('admin_page', $data); // 進階管理者介面
}
else
{
$this->show_page('main_page', $data); // 一般管理者介面
}
}
else
{
//If no session, redirect to login page
//redirect('login', 'refresh');
$this->show_page('login_page');
}
}
// 登入
public function user_login()
{
// form_validation
$this->form_validation->set_rules('login_name', 'login_name', 'trim|required|xss_clean');
$this->form_validation->set_rules('pswd', 'pswd', 'trim|required|xss_clean');
if($this->form_validation->run() == FALSE)
{
return RESULT_FORM_VALIDATION_FAIL;
}
// go model
$data = array
(
'login_name' => $this->input->post('login_name', true),
'pswd' => $this->input->post('pswd', true)
);
$result = $this->vip_model->user_login($data);
if($result)
{
$sess_array = array();
foreach($result as $row)
{
$sess_array = array
(
'username' => $row->login_name ,
'type' => $row->type
);
$this->session->set_userdata('logged_in', $sess_array);
}
echo RESULT_SUCCESS;
}
else
{
return RESULE_FAIL;
}
}
// 登出
public function user_logout()
{
$this->session->unset_userdata('logged_in');
session_destroy();
return RESULT_SUCCESS;
}
// 新增與修改
public function member_add()
{
// form_validation (required)
$this->form_validation->set_rules('member_no', 'member_no', 'trim|required|xss_clean');
$this->form_validation->set_rules('station_no', 'station_no', 'trim|required|xss_clean');
$this->form_validation->set_rules('lpr', 'lpr', 'trim|required|xss_clean|alpha_numeric');
$this->form_validation->set_rules('start_date', 'start_date', 'trim|required|xss_clean');
$this->form_validation->set_rules('end_date', 'end_date', 'trim|required|xss_clean');
$this->form_validation->set_rules('member_name', 'member_name', 'trim|required|xss_clean');
$this->form_validation->set_rules('mobile_no', 'mobile_no', 'trim|required|xss_clean');
// form_validation (basic)
$this->form_validation->set_rules('remarks', 'remarks', 'trim|xss_clean');
if($this->form_validation->run() == FALSE)
{
return RESULT_FORM_VALIDATION_FAIL;
}
// go model
$data = array
(
'member_no' => $this->input->post('member_no', true),
'station_no' => $this->input->post('station_no', true),
'lpr' => strtoupper($this->input->post('lpr', true)),
'start_date' => $this->input->post('start_date', true),
'end_date' => $this->input->post('end_date', true),
'member_name' => $this->input->post('member_name', true),
'member_nick_name' => $this->input->post('member_name', true),
'mobile_no' => $this->input->post('mobile_no', true),
'remarks' => $this->input->post('remarks', true)
);
$this->vip_model->vip_add($data);
echo RESULT_SUCCESS;
}
// 查詢
public function member_query()
{
$data = $this->vip_model->vip_query();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 刪除
public function member_delete()
{
// form_validation
$this->form_validation->set_rules('member_no', 'member_no', 'trim|required|xss_clean');
if($this->form_validation->run() == FALSE)
{
return RESULE_FAIL;
}
// go model
$member_no = $this->input->post('member_no', true);
$this->vip_model->member_delete($member_no);
echo RESULT_SUCCESS;
}
// 管理者新增與修改
public function user_add()
{
// 判斷target_name分流insert or update
$this->form_validation->set_rules('target_name', 'target_name', 'trim|xss_clean');
// form_validation (basic)
$this->form_validation->set_rules('type', 'type', 'trim|required|xss_clean');
$this->form_validation->set_rules('user_name', 'user_name', 'trim|xss_clean');
$this->form_validation->set_rules('email', 'email', 'trim|xss_clean');
$this->form_validation->set_rules('mobile_no', 'mobile_no', 'trim|xss_clean');
$this->form_validation->set_rules('tel', 'tel', 'trim|xss_clean');
$this->form_validation->set_rules('car_plate', 'car_plate', 'trim|xss_clean');
if($this->form_validation->run() == FALSE)
{
return RESULT_FORM_VALIDATION_FAIL;
}
$target_name = $this->input->post('target_name', true);
if($target_name == '')
{
// insert 流程
// form_validation (required)
$this->form_validation->set_rules('login_name', 'login_name', 'trim|required|xss_clean');
$this->form_validation->set_rules('pswd', 'pswd', 'trim|required|xss_clean');
if($this->form_validation->run() == FALSE)
{
return RESULT_FORM_VALIDATION_FAIL;
}
// go model
$data = array
(
'type' => $this->input->post('type', true),
'login_name' => $this->input->post('login_name', true),
'pswd' => MD5($this->input->post('pswd', true)),
'user_name' => $this->input->post('user_name', true),
'email' => $this->input->post('email', true),
'mobile_no' => $this->input->post('mobile_no', true),
'tel' => $this->input->post('tel', true),
'car_plate' => strtoupper($this->input->post('car_plate', true))
);
$this->vip_model->user_insert($data);
echo RESULT_SUCCESS;
}
else
{
// update 流程
// go model
$data = array
(
'type' => $this->input->post('type', true),
'user_name' => $this->input->post('user_name', true),
'email' => $this->input->post('email', true),
'mobile_no' => $this->input->post('mobile_no', true),
'tel' => $this->input->post('tel', true),
'car_plate' => strtoupper($this->input->post('car_plate', true))
);
$this->vip_model->user_update($data, $target_name);
echo RESULT_SUCCESS;
}
}
// 管理者查詢
public function user_query()
{
$data = $this->vip_model->user_query();
echo json_encode($data, JSON_UNESCAPED_UNICODE);
}
// 管理者刪除
public function user_delete()
{
// form_validation
$this->form_validation->set_rules('login_name', 'login_name', 'trim|required|xss_clean');
if($this->form_validation->run() == FALSE)
{
return RESULE_FAIL;
}
// go model
$login_name = $this->input->post('login_name', true);
$this->vip_model->user_delete($login_name);
echo RESULT_SUCCESS;
}
}

+ 109
- 0
controllers/Vip_parked.php 파일 보기

@@ -0,0 +1,109 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
file: vip_parked.php VIP車位
http://192.168.10.201/vip_parked.html/pages/1
舊版:
file:///C:/altob/vip/javascript_mqtt/vip_parked.html
*/
require_once(MQ_CLASS_FILE);
class Vip_parked extends CI_Controller
{
var $vars = array();
function __construct()
{
parent::__construct();
$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; // 本站編號
/*
// cameras or etagio直接release連線(即斷線), 但繼續處理邏輯
$method_name = $this->router->fetch_method();
if ($method_name == 'cameras' || $method_name == 'etagio')
{
ob_end_clean();
ignore_user_abort();
ob_start();
header('Connection: close');
header('Content-Length: ' . ob_get_length());
ob_end_flush();
flush();
}
*/
// ----- 程式開發階段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', 'vip_parked'); // 應用系統名稱
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/cario.'); // log file name
}
// 發生錯誤時集中在此處理
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代表參考後面的檔名
}
public function pages()
{
$data['vip_no'] = $this->uri->segment(3); // vip no
$data['mqtt_ip'] = '192.168.51.11';
$this->load->view(APP_NAME.'/main_page', $data);
}
public function vip_welcome()
{
$this->load->view(APP_NAME.'/vip_welcome');
}
public function parked()
{
$this->load->view(APP_NAME.'/vip_welcome');
}
}

+ 11
- 0
controllers/index.html 파일 보기

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

+ 250
- 0
coworker/acer2server.php 파일 보기

@@ -0,0 +1,250 @@
<?php
require_once '/home/bigbang/libs/Workerman/Autoloader.php';
use Workerman\Worker;
Worker::$logFile = '/dev/null'; // 不記錄log file
//Worker::$pidFile = '/tmp/run/'.basename(__FILE__).'.pid';
//Worker::$logFile = __DIR__ . '/../acer2server.log';
// 場站共用設定檔
require_once '/home/bigbang/apps/coworker/station.config.php';
define('APP_NAME', 'acer'); // application name
define('WORKERMAN_DEBUG', 1);
if (WORKERMAN_DEBUG)
{
ini_set('display_errors', '1');
error_reporting(E_ALL);
set_error_handler('error_handler', E_ALL);
}
///////////////////////////////
//
// 回傳代碼定義
//
///////////////////////////////
// 結果代碼
define('ALTOB_RESULT_CODE_SUCCESS', 'OK'); // 成功
define('ALTOB_RESULT_CODE_FAIL', 'GG'); // 失敗
// 錯誤碼
define('ALTOB_ERROR_CODE_NONE', '0000'); // 預設值 (成功帶這個)
define('ALTOB_ERROR_CODE_UNKNOWN_INPUT', '1001'); // 未知的 輸入
define('ALTOB_ERROR_CODE_UNKNOWN_CMD', '1002'); // 未知的 CMD
define('ALTOB_ERROR_CODE_UNDEFINED', '9999'); // 未定義的錯誤
define('ALTOB_ERROR_CODE_ACER_RESULT_FAIL', '2001'); // ACER 回傳處理錯誤
///////////////////////////////
//
// 主程式
//
///////////////////////////////
// 傳送主機資料
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true); // 啟用POST
// 建立一個Worker監聽8033埠,不使用任何應用層協定
$tcp_worker = new Worker("tcp://0.0.0.0:8033");
// 啟動N個進程對外提供服務
$tcp_worker->count = 4;
$tcp_worker->onConnect = function($connection)
{
echo "New Connection\n";
};
$tcp_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// 當用戶端發來數據(主程式)
$tcp_worker->onMessage = function($connection, $tcp_in)
{
global $ch;
$explode_tcp_in = explode(chr(28), $tcp_in); // 0x1C tcp欄位分隔
$send_data = null;
if(empty($explode_tcp_in) || count($explode_tcp_in) != 5)
{
trigger_error(".. unknown tcp_in|". print_r($explode_tcp_in, true) .'|');
$send_data = gen_error_result(ALTOB_ERROR_CODE_UNKNOWN_INPUT);
}
else
{
list(, $seq, $cmd, $data, ) = $explode_tcp_in;
$seq = 1;
switch($cmd)
{
// 票卡入場訊號,供 ALTOB 登記
case '001':
//(傳入:卡號、入場編號、是否月租卡; 回傳:成功、入場編號)
list($card_no, $cario_no, $card_type) = explode(chr(31), $data); // 0x1F data欄位分隔
trigger_error("cmd:{$cmd}, card_no:{$card_no}, cario_no:{$cario_no}, card_type:{$card_type}");
// 呼叫 cmd_001
$data = array('card_no' => $card_no, 'cario_no' => $cario_no, 'card_type' => $card_type);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_001/');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$jdata = curl_exec($ch);
$result = json_decode($jdata, true);
trigger_error("{$cmd}|{$card_no}|{$cario_no}|{$card_type}|result|" . print_r($result, true));
$send_data = gen_cario_result($seq, $cmd,
$result['result_code'],
$result['result']['cario_no'],
$result['result']['error_code']);
break;
// 票卡離場訊號,供 ALTOB 登記
case '002':
//(傳入:卡號、繳費時間、是否月租卡; 回傳:成功、入場編號)
list($card_no, $pay_time, $card_type) = explode(chr(31), $data); // 0x1F data欄位分隔
trigger_error("cmd:{$cmd}, card_no:{$card_no}, pay_time:{$pay_time}, card_type:{$card_type}");
// 呼叫 cmd_002
$data = array('card_no' => $card_no, 'pay_time' => $pay_time, 'card_type' => $card_type);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_002/');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$jdata = curl_exec($ch);
$result = json_decode($jdata, true);
trigger_error("{$cmd}|{$card_no}|{$pay_time}|{$card_type}|result|" . print_r($result, true));
$send_data = gen_cario_result($seq, $cmd,
$result['result_code'],
$result['result']['cario_no'],
$result['result']['error_code']);
break;
// 票號離場訊號,回傳若成功觸發 ACER 開門
case '003':
// (傳入:6 碼數字; 回傳:入場編號、成功與否代號)
list($ticket_no) = explode(chr(31), $data); // 0x1F data欄位分隔
trigger_error("cmd:{$cmd}, ticket_no:{$ticket_no}");
// 呼叫 cmd_003
$data = array('ticket_no' => $ticket_no);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/acer_service.html/cmd_003/');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$jdata = curl_exec($ch);
$result = json_decode($jdata, true);
trigger_error("{$cmd}|{$ticket_no}|result|" . print_r($result, true));
$send_data = gen_cario_result($seq, $cmd,
$result['result_code'],
$result['result']['cario_no'],
$result['result']['error_code'],
$result['result']['msg_code']);
break;
default:
trigger_error(".. unknown cmd | {$seq}, {$cmd}, {$data}|");
$send_data = gen_error_result(ALTOB_ERROR_CODE_UNKNOWN_CMD);
break;
}
}
// 未定義的錯誤
if(empty($send_data))
{
$send_data = gen_error_result(ALTOB_ERROR_CODE_UNDEFINED);
}
$connection->close($send_data);
};
// 執行worker
Worker::runAll();
// 產生錯誤回傳
function gen_error_result($error_code)
{
return gen_cario_result(0, 0, ALTOB_RESULT_CODE_FAIL, 0, $error_code);
}
// 產生 cario_no 回傳
function gen_cario_result($seq, $cmd, $result_code, $cario_no, $error_code, $msg_code=0)
{
$send_data = '';
$seq_pad = str_pad($seq, 5, '0', STR_PAD_LEFT); // 序號: 5 碼 (左邊補 0)
$cmd_pad = str_pad($cmd, 3, '0', STR_PAD_LEFT); // 指令: 3 碼 (左邊補 0)
$cario_no_pad = str_pad($cario_no, 10, '0', STR_PAD_LEFT); // 入場編號: 10 碼 (左邊補 0)
$error_code_pad = str_pad($error_code, 4, '0', STR_PAD_LEFT); // 錯誤碼: 4 碼 (左邊補 0)
$msg_code_pad = str_pad($msg_code, 5, '0', STR_PAD_LEFT); // 離場代碼: 5 碼 (左邊補 0)
trigger_error(__FUNCTION__ . "..{$seq_pad}|{$cmd_pad}|{$cario_no_pad}|{$error_code_pad}|{$msg_code_pad}..");
if(empty($msg_code))
{
$packformat = "a2Ca10Ca4";
$data = pack($packformat,
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
//trigger_error(".. TEST socket_len | {$socket_len}, {$data_len}|". intval($socket_len / 0x0100). '_'. intval($socket_len % 0x0100));
$send_data = pack("Ca2Ca5Ca3C{$packformat}CCC",
0x02, // STX:封包起始碼(0x02)
$socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
$seq_pad, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
$cmd_pad, 0x1c, // CmdID:命令ID
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad,
0x1c,
0x80, // CRC:封包檢查碼
0x03 // ETX:封包結束碼(0x03)
);
}
else
{
$packformat = "a2Ca10Ca4Ca5";
$data = pack($packformat,
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad, 0x1f, $msg_code_pad
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
//trigger_error(".. TEST socket_len | {$socket_len}, {$data_len}|". intval($socket_len / 0x0100). '_'. intval($socket_len % 0x0100));
$send_data = pack("Ca2Ca5Ca3C{$packformat}CCC",
0x02, // STX:封包起始碼(0x02)
$socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
$seq_pad, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
$cmd_pad, 0x1c, // CmdID:命令ID
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$result_code, 0x1f, $cario_no_pad, 0x1f, $error_code_pad, 0x1f, $msg_code_pad,
0x1c,
0x80, // CRC:封包檢查碼
0x03 // ETX:封包結束碼(0x03)
);
}
return $send_data;
}
// 發生錯誤時集中在此處理
function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
}

+ 322
- 0
coworker/parktron2server_fuzzy.php 파일 보기

@@ -0,0 +1,322 @@
<?php
// 博辰設備對接
// php //home/bigbang/apps/coworker/parktron2server.php
require_once '/home/bigbang/libs/Workerman/Autoloader.php';
use Workerman\Worker;
Worker::$logFile = '/dev/null'; // 不記錄log file
//Worker::$pidFile = '/tmp/run/'.basename(__FILE__).'.pid';
// 傳送主機資料
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true); // 啟用POST
// 建立一個Worker監聽8068埠,不使用任何應用層協定
$tcp_worker = new Worker("tcp://0.0.0.0:8068");
// 啟動N個進程對外提供服務
$tcp_worker->count = 6;
$tcp_worker->onConnect = function($connection)
{
echo "New Connection\n";
};
$tcp_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// 當用戶端發來數據(主程式)
$tcp_worker->onMessage = function($connection, $tcp_in)
{
global $ch, $last_lpr;
// echo 'start time:'.date('Y-m-d H:i:s');
list(, $seq, $cmd, $data) = explode(chr(28), $tcp_in); // 0x1C tcp欄位分隔
// echo "data_in:[{$seq}|{$cmd}|{$data}|]\n";
switch($cmd)
{
case '001': // 車輛入場
list($devno, $token, $lpr, $in_time, $last_field) = explode(chr(31), $data); // 0x1F data欄位分隔
$type = substr($last_field, 0, -2);
echo "{$devno}|{$token}|{$lpr}|{$in_time}|{$type}|\n";
$connection->send('OK');
break;
case '002': // APS詢問車牌入場時間
list($token, $lpr, $last_field) = explode(chr(31), $data); // 0x1F data欄位分隔
$lpr = str_replace('%', '', $lpr);
$last_lpr = $lpr;
$in_time = substr($last_field, 0, -2);
// echo "cmd_002:[{$token}|{$lpr}|{$in_time}|]/n";
$data = array('lpr' => $lpr);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/carpayment.html/query_in_fuzzy/');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$jdata = curl_exec($ch);
$results = json_decode($jdata, true);
$connection->send(tcp_data_fuzzy($results['count'], $results['results'], '001', '002'));
break;
case '003': // 繳費完成
list($ticket_no, $lpr, $in_time, $pay_time, $last_field) = explode(chr(31), $data); // 0x1F data欄位分隔
$pay_type = substr($last_field, 0, -2);
// echo "{$ticket_no}|{$lpr}|{$in_time}|{$pay_time}|{$pay_type}|/n";
$connection->send('OK');
//if ($lpr == '*******') {$lpr = $last_lpr; $err_lpr = '***';}
if ($lpr == '*******') {$err_lpr = '***';}
else
{ $err_lpr = '+++';}
// 傳送繳費資料
$data = array
(
'ticket_no' => $ticket_no, // 票卡號碼
'lpr' => $lpr, // 車號
'in_time' => $in_time, // 入場時間
'pay_time' => $pay_time, // 繳款時間
'pay_type' => $pay_type // 繳款方式(0:現金, 1:月票, 2:多卡通)
);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/carpayment.html/p2payed/');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$results = curl_exec($ch);
file_put_contents('/tmp/aps.log.txt', date('Y-m-d H:i:s').":{$err_lpr}\n".print_r($data, true)."\n\n", FILE_APPEND);
break;
}
// echo 'end_time:'.date('Y-m-d H:i:s');
};
function tcp_data_fuzzy($records_count, $records, $seq, $cmdid)
{
$seq = '00001';
$cmdid = '002';
$packformat = 'aC';
// 0 筆
if($records_count == 0)
{
$count = 0;
$data = pack($packformat,
"{$count}", 0x1f
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
"{$count}", 0x1f,
0x80, 0x03);
return $send_data;
}
// 1. create data
foreach ($records as $idx => $rows)
{
$pathlen = strlen($rows['in_pic_name']);
$packformat = $packformat."A7Ca7CaCa19Ca{$pathlen}Ca19Ca10Ca10Ca5Ca5C";
}
if(count($records) == 1)
{
$count = 1;
$data = pack($packformat,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
0x80, 0x03);
}
else if(count($records) == 2)
{
$count = 2;
$data = pack($packformat,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
0x80, 0x03);
}
else if(count($records) == 3)
{
$count = 3;
$data = pack($packformat,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f,
0x80, 0x03);
}
else if(count($records) == 4)
{
$count = 4;
$data = pack($packformat,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f,
$records[3]['lpr'], 0x1f, $records[3]['seat_no'], 0x1f, $records[3]['ticket'], 0x1f, $records[3]['in_time'], 0x1f, $records[3]['in_pic_name'], 0x1f, $records[3]['pay_time'], 0x1f, $records[3]['start_date'], 0x1f, $records[3]['end_date'], 0x1f, $records[3]['start_time'], 0x1f, $records[3]['end_time'], 0x1f
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f,
$records[3]['lpr'], 0x1f, $records[3]['seat_no'], 0x1f, $records[3]['ticket'], 0x1f, $records[3]['in_time'], 0x1f, $records[3]['in_pic_name'], 0x1f, $records[3]['pay_time'], 0x1f, $records[3]['start_date'], 0x1f, $records[3]['end_date'], 0x1f, $records[3]['start_time'], 0x1f, $records[3]['end_time'], 0x1f,
0x80, 0x03);
}
else if(count($records) == 5)
{
$count = 5;
$data = pack($packformat,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f,
$records[3]['lpr'], 0x1f, $records[3]['seat_no'], 0x1f, $records[3]['ticket'], 0x1f, $records[3]['in_time'], 0x1f, $records[3]['in_pic_name'], 0x1f, $records[3]['pay_time'], 0x1f, $records[3]['start_date'], 0x1f, $records[3]['end_date'], 0x1f, $records[3]['start_time'], 0x1f, $records[3]['end_time'], 0x1f,
$records[4]['lpr'], 0x1f, $records[4]['seat_no'], 0x1f, $records[4]['ticket'], 0x1f, $records[4]['in_time'], 0x1f, $records[4]['in_pic_name'], 0x1f, $records[4]['pay_time'], 0x1f, $records[4]['start_date'], 0x1f, $records[4]['end_date'], 0x1f, $records[4]['start_time'], 0x1f, $records[4]['end_time'], 0x1f
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f,
$records[3]['lpr'], 0x1f, $records[3]['seat_no'], 0x1f, $records[3]['ticket'], 0x1f, $records[3]['in_time'], 0x1f, $records[3]['in_pic_name'], 0x1f, $records[3]['pay_time'], 0x1f, $records[3]['start_date'], 0x1f, $records[3]['end_date'], 0x1f, $records[3]['start_time'], 0x1f, $records[3]['end_time'], 0x1f,
$records[4]['lpr'], 0x1f, $records[4]['seat_no'], 0x1f, $records[4]['ticket'], 0x1f, $records[4]['in_time'], 0x1f, $records[4]['in_pic_name'], 0x1f, $records[4]['pay_time'], 0x1f, $records[4]['start_date'], 0x1f, $records[4]['end_date'], 0x1f, $records[4]['start_time'], 0x1f, $records[4]['end_time'], 0x1f,
0x80, 0x03);
}
else if(count($records) == 6)
{
$count = 6;
$data = pack($packformat,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f,
$records[3]['lpr'], 0x1f, $records[3]['seat_no'], 0x1f, $records[3]['ticket'], 0x1f, $records[3]['in_time'], 0x1f, $records[3]['in_pic_name'], 0x1f, $records[3]['pay_time'], 0x1f, $records[3]['start_date'], 0x1f, $records[3]['end_date'], 0x1f, $records[3]['start_time'], 0x1f, $records[3]['end_time'], 0x1f,
$records[4]['lpr'], 0x1f, $records[4]['seat_no'], 0x1f, $records[4]['ticket'], 0x1f, $records[4]['in_time'], 0x1f, $records[4]['in_pic_name'], 0x1f, $records[4]['pay_time'], 0x1f, $records[4]['start_date'], 0x1f, $records[4]['end_date'], 0x1f, $records[4]['start_time'], 0x1f, $records[4]['end_time'], 0x1f,
$records[5]['lpr'], 0x1f, $records[5]['seat_no'], 0x1f, $records[5]['ticket'], 0x1f, $records[5]['in_time'], 0x1f, $records[5]['in_pic_name'], 0x1f, $records[5]['pay_time'], 0x1f, $records[5]['start_date'], 0x1f, $records[5]['end_date'], 0x1f, $records[5]['start_time'], 0x1f, $records[5]['end_time'], 0x1f
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
"{$count}", 0x1f,
$records[0]['lpr'], 0x1f, $records[0]['seat_no'], 0x1f, $records[0]['ticket'], 0x1f, $records[0]['in_time'], 0x1f, $records[0]['in_pic_name'], 0x1f, $records[0]['pay_time'], 0x1f, $records[0]['start_date'], 0x1f, $records[0]['end_date'], 0x1f, $records[0]['start_time'], 0x1f, $records[0]['end_time'], 0x1f,
$records[1]['lpr'], 0x1f, $records[1]['seat_no'], 0x1f, $records[1]['ticket'], 0x1f, $records[1]['in_time'], 0x1f, $records[1]['in_pic_name'], 0x1f, $records[1]['pay_time'], 0x1f, $records[1]['start_date'], 0x1f, $records[1]['end_date'], 0x1f, $records[1]['start_time'], 0x1f, $records[1]['end_time'], 0x1f,
$records[2]['lpr'], 0x1f, $records[2]['seat_no'], 0x1f, $records[2]['ticket'], 0x1f, $records[2]['in_time'], 0x1f, $records[2]['in_pic_name'], 0x1f, $records[2]['pay_time'], 0x1f, $records[2]['start_date'], 0x1f, $records[2]['end_date'], 0x1f, $records[2]['start_time'], 0x1f, $records[2]['end_time'], 0x1f,
$records[3]['lpr'], 0x1f, $records[3]['seat_no'], 0x1f, $records[3]['ticket'], 0x1f, $records[3]['in_time'], 0x1f, $records[3]['in_pic_name'], 0x1f, $records[3]['pay_time'], 0x1f, $records[3]['start_date'], 0x1f, $records[3]['end_date'], 0x1f, $records[3]['start_time'], 0x1f, $records[3]['end_time'], 0x1f,
$records[4]['lpr'], 0x1f, $records[4]['seat_no'], 0x1f, $records[4]['ticket'], 0x1f, $records[4]['in_time'], 0x1f, $records[4]['in_pic_name'], 0x1f, $records[4]['pay_time'], 0x1f, $records[4]['start_date'], 0x1f, $records[4]['end_date'], 0x1f, $records[4]['start_time'], 0x1f, $records[4]['end_time'], 0x1f,
$records[5]['lpr'], 0x1f, $records[5]['seat_no'], 0x1f, $records[5]['ticket'], 0x1f, $records[5]['in_time'], 0x1f, $records[5]['in_pic_name'], 0x1f, $records[5]['pay_time'], 0x1f, $records[5]['start_date'], 0x1f, $records[5]['end_date'], 0x1f, $records[5]['start_time'], 0x1f, $records[5]['end_time'], 0x1f,
0x80, 0x03);
}
return $send_data;
}
function tcp_data($arr, $seq, $cmdid)
{
$crc = pack('C', 'X'); // 起始值
$seq = '00001';
$cmdid = '002';
$pathlen = strlen($arr['pic_name']);
$packformat = "aCA7Ca7CaCa19Ca{$pathlen}Ca19Ca10Ca10Ca5Ca5C";
// $packformat = "aCA7Ca7CaCa19Ca71Ca19Ca10Ca10Ca5Ca5C";
$data = pack($packformat,
$arr['nth'], 0x1f,
$arr['lpr'], 0x1f,
$arr['seat_no'], 0x1f,
$arr['ticket'], 0x1f,
$arr['start_time'], 0x1f,
$arr['pic_name'], 0x1f,
$arr['pay_time'], 0x1f,
$arr['ticket_start_date'], 0x1f,
$arr['ticket_end_date'], 0x1f,
$arr['ticket_start_time'], 0x1f,
$arr['ticket_end_time'], 0x1f);
$data_len = strlen($data);
$socket_len = $data_len + 16;
// echo "len data[{$data_len}] socket[{$socket_len}] data[{$data}]";
$send_data = pack("CCCCa5Ca3C{$packformat}CC",
0x02,
$socket_len / 0x0100, $socket_len % 0x0100, 0x1c, $seq, 0x1c, $cmdid, 0x1c,
$arr['nth'], 0x1f,
$arr['lpr'], 0x1f,
$arr['seat_no'], 0x1f,
$arr['ticket'], 0x1f,
$arr['start_time'], 0x1f,
$arr['pic_name'], 0x1f,
$arr['pay_time'], 0x1f,
$arr['ticket_start_date'], 0x1f,
$arr['ticket_end_date'], 0x1f,
$arr['ticket_start_time'], 0x1f,
$arr['ticket_end_time'], 0x1f,
0x80, 0x03);
// echo 'len:[' . $socket_len. '] send_data:['. $send_data .']';
// file_put_contents('/tmp/aps.log.txt', date('Y-m-d H:i:s')."\n".$send_data ."\n\n", FILE_APPEND);
return $send_data;
}
// 執行worker
Worker::runAll();

+ 15
- 0
coworker/station.config.php 파일 보기

@@ -0,0 +1,15 @@
<?php
/*
file: station.config.php 資料庫設定帳密設定
*/
define('MEMCACHE_HOST', 'localhost'); // memcache host
define('MEMCACHE_PORT', 11211); // memcache post no (default:11211)
define('LOG_PATH', '/home/data/logs/');
$dbs['host'] = 'localhost';
$dbs['dbname'] = 'master_db';
$dbs['user_name'] = 'altob';
$dbs['password'] = '0227057716';
$dbs['dsn'] = "mysql:host={$dbs['host']};dbname={$dbs['dbname']};charset=utf8";

+ 439
- 0
coworker/station_services.php 파일 보기

@@ -0,0 +1,439 @@
<?php
/*
-----
file: station_services.php 場站應用系統服務程式
workerman執行:
/usr/bin/php /home/bigbang/apps/coworker/station_services.php start -d
workerman停止
/usr/bin/php /home/bigbang/apps/coworker/station_services.php stop
-----
*/
require_once '/home/bigbang/libs/Workerman/Autoloader.php';
use Workerman\Worker;
Worker::$logFile = '/dev/null'; // 不記錄log file
//Worker::$pidFile = '/home/bigbang/libs/Workerman/' .basename(__FILE__).'.pid';
// 場站共用設定檔
require_once '/home/bigbang/apps/coworker/station.config.php';
define('APP_NAME', 'stations'); // application name
// 序號檔路徑
define('SEQNO_PATH', '/home/data/seqno/');
define('WORKERMAN_DEBUG', 1);
if (WORKERMAN_DEBUG)
{
ini_set('display_errors', '1');
error_reporting(E_ALL);
set_error_handler('error_handler', E_ALL);
}
// 每月最後一日
$last_date_month = array
(
1 => 31,
2 => 28,
3 => 31,
4 => 30,
5 => 31,
6 => 30,
7 => 31,
8 => 31,
9 => 30,
10 => 31,
11 => 30,
12 => 31
);
$xvars = array(); // 共用變數
// 共用記憶體
$mem = new Memcache;
if (! $mem->pconnect(MEMCACHE_HOST, MEMCACHE_PORT))
{
echo 'Could not connect memcache';
Worker::stopAll();
}
// 連接總管理處資料庫
$pdo = new PDO($dbs['dsn'], $dbs['user_name'], $dbs['password']);
// 讀取info場站共用資訊
$sql_info = 'select station_no, station_name, station_full_name, company_no, station_ip, hq_url, origin_url, period_name, park_time,member_attr_list, period_list from info where seqno = 1';
$info_arr = $pdo->query($sql_info)->fetch(PDO::FETCH_ASSOC);
// global variable
$pdo = null;
$query_syncs = null;
$query_sync2hq_ok = null;
// 未同步者批次同步至總管理處
$sql_syncs = 'select st_sync_no, station_no, act, hq_tname, st_tname, st_seqno, sync_data from syncs where synced = 0 and st_sync_no = ?';
// $query_syncs = $pdo->prepare($sql_syncs);
// 同步成功
$sql_sync2hq_ok = 'update syncs set synced = 1, hq_sync_no = ? where st_sync_no = ?';
// $query_sync2hq_ok = $pdo->prepare($sql_sync2hq_ok);
// 預設curl參數
$curl_ch = curl_init();
$curl_options = array
(
CURLOPT_URL => $info_arr['hq_url'],
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1, // 返回值不顯示, 只做變數用
CURLOPT_POST => 1,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 5
);
init_station_xvars();
// 建立一個Worker監聽60133埠,不使用任何應用層協定
$worker = new Worker("http://0.0.0.0:60133");
// 啟動N個進程對外提供服務
$worker->count = 4;
// ----- program start -----
// 當用戶端發來數據(主程式)
$worker->onMessage = function($connection, $msg_in)
{
global $dbs, $pdo, $sql_syncs, $sql_sync2hq_ok, $query_syncs, $query_sync2hq_ok;
// 無連線或status != Localhost via UNIX socket, 重連線之
if (empty($pdo) || preg_match('/socket$/', $pdo->getAttribute(PDO::ATTR_CONNECTION_STATUS)) != 1 )
{
$pdo = new PDO($dbs['dsn'], $dbs['user_name'], $dbs['password'], array(PDO::ATTR_PERSISTENT => true));
$query_syncs = $pdo->prepare($sql_syncs);
$query_sync2hq_ok = $pdo->prepare($sql_sync2hq_ok);
trigger_error('new pdo');
}
if (!empty($_REQUEST['cmd']))
{
trigger_error('worker.onMessage: ' . print_r($_REQUEST, true));
$funcs = @$_REQUEST['cmd'];
$funcs($connection);
}
};
// 執行worker
Worker::runAll();
// ----- end of program -----
// 同步化, 場站 -> 總管理處 , 參數:
// http://hq_ip:60133/?cmd=st_syncs&station_no=12110&act=U&tname=members&key=member_no&kval=12110101&jdata=json_str&ck=str32
function st_syncs($connection)
{
global $pdo_hq, $query_hq_sync;
// 暫不驗證
$syncs_sql = parms2sql($_REQUEST);
// exec:傳回筆數, query:傳回資料
$rows_affected = $pdo_hq->exec($syncs_sql);
// 如果新增資料, 回傳insert ID
if ($_REQUEST['act'] == 'A') $rows_affected = $pdo_hq->lastInsertId();
@$connection->send($rows_affected); // 回應當前序號或筆數
$confirms = $rows_affected > 0 ? 1 : 0;
$query_hq_sync->execute(array($_REQUEST['station_no'], $_REQUEST['act'], $_REQUEST['tname'], $_REQUEST['data'], $confirms));
}
// 讀取序號
// http://localhost:60133/?cmd=seqno&seqname=members&init_no=1025
function seqno($connection)
{
$seqno_fname = SEQNO_PATH . "{$_REQUEST['seqname']}.txt";
$fp = fopen($seqno_fname, 'r+');
// lock, 讀入序號, 加1寫回, close
if ($fp)
{
flock($fp, LOCK_EX);
$seqno = fread($fp, 80);
$next_no = $seqno + 1;
rewind($fp);
fwrite($fp, $next_no);
flock($fp, LOCK_UN);
fclose($fp);
}
else // 如無此序號檔, 新建之, 並傳回初始值
{
$seqno = empty($_REQUEST['init_no']) ? 1 : $_REQUEST['init_no'];
$next_no = $seqno + 1;
file_put_contents($seqno_fname, $next_no, FILE_APPEND);
}
@$connection->send($seqno); // 回應當前序號
}
// 檢查是否有連線 ?
function check_connect($connection)
{
$connected = @fsockopen($_REQUEST['ip'], $_REQUEST['port'], $errno, $errstr, $_REQUEST['timeout']);
if ($connected)
{
fclose($connected);
$is_connected = 1; //action when connected
}
else
{
$is_connected = 0; //action in connection failure
}
return $is_connected;
}
// 取得下一租期期最後一日
function last_date_next($connection)
{
@cross_header();
@$connection->send(last_date_next_period($_REQUEST['last_date_curr'], $_REQUEST['fee_period'])); // 參數:本期截止日,繳期
}
// 取得下一租期期最後一日, 參數: 本期截止日, 繳期
function last_date_next_period($last_date_curr, $fee_period)
{
global $last_date_month;
$arr = explode('-', $last_date_curr);
$yy = (int) $arr[0]; // 取年份
$mm = (int) $arr[1]; // 取月份
$mm += $fee_period;
if ($mm > 12) // 超過12月, 年度+1, 折算明年度月份
{
++$yy;
$mm -= 12;
}
$dd = $mm == 2 && ($yy % 4) == 0 ? 29 : $last_date_month[$mm];
if ($mm < 10) $mm = "0{$mm}"; // 個位數前面補0
return "{$yy}-{$mm}-{$dd}";
}
// web跨網域header設定
function cross_header()
{
global $info_arr;
\Workerman\Protocols\Http::header('Access-Control-Allow-Origin: ' . "{$info_arr['origin_url']}");
\Workerman\Protocols\Http::header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
\Workerman\Protocols\Http::header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept');
}
// 將參數轉成sql命令字串
function parms2sql($parms)
{
$act = $parms['act'];
switch($act)
{
case 'U': // 更新場站資料庫 ????
$sql = "update {$parms['tname']} set {$parms['data']} where {$parms['key']} = '{$parms['kval']}';";
break;
case 'A': // 新增資料
$fields_str = implode(',', array_keys($data));
$values_str = "'".implode("',", array_values($data))."'";
$sql = "insert into {$parms['tname']} ({$fields_str}) values({$values_str});";
break;
case 'D': // 刪除資料
$sql = "delete {$parms['tname']} where {$parms['key']} = '{$parms['kval']}';";
break;
}
}
// 場站初始化參數
function init_station_xvars()
{
global $mem, $info_arr, $xvars;
$data = array
(
'cmd' => 'init_station',
'station_no' => $info_arr['station_no'],
'park_time' => $info_arr['park_time']
);
$jdata = worker_tx($data);
if(empty($jdata))
{
trigger_error('中控已斷線, 建立預設值..'.print_r($jdata, true));
// 中控已斷線, 建立預設值
$xvars = array();
$xvars['info']['period_name'] = array(1 => "月繳", 2 => "雙月繳", 3 => "季繳", 6 => "雙季繳", 12 => "四季繳");
$xvars['info']['member_attr'] = array(1 => "一般", 2 => "里民", 3 => "身障", 4 => "員工", 5 => "里長", 250 => "VIP");
$xvars['pt'] =
array(
'RE' => array(
'seqno' => 1000,
'timex' => array(
'0' => array('type' => 1, 'w_start' => 0, 'w_end' => 6, 'time_start' => '00:00:00', 'time_end' => '23:59:59')
),
'remarks' => '全天全時段'
),
'NF' => array(
'seqno' => 1010,
'timex' => array(
'0' => array('type' => 1, 'w_start' => 1, 'w_end' => 5, 'time_start' => '18:00:00', 'time_end' => '23:59:59'),
'1' => array('type' => 1, 'w_start' => 1, 'w_end' => 5, 'time_start' => '00:00:00', 'time_end' => '07:59:59')
),
'remarks' => '週一至週五: 00:00:00 - 07:59:59 <br/>週一至週五: 18:00:00 - 23:59:59'
),
'WK66' => array(
'seqno' => 1026,
'timex' => array(
'0' => array('type' => 1, 'w_start' => 1, 'w_end' => 5, 'time_start' => '06:00:00', 'time_end' => '17:59:59')
),
'remarks' => '週一至週五: 06:00:00 - 17:59:59'
),
'WK' => array(
'seqno' => 1020,
'timex' => array(
'0' => array('type' => 1, 'w_start' => 1, 'w_end' => 5, 'time_start' => '07:30:00', 'time_end' => '18:29:59')
),
'remarks' => '週一至週五: 07:30:00 - 18:29:59'
),
'HO' => array(
'seqno' => 1030,
'timex' => array(
'0' => array('type' => 1, 'w_start' => 6, 'w_end' => 6, 'time_start' => '00:00:00', 'time_end' => '23:59:59'),
'1' => array('type' => 1, 'w_start' => 0, 'w_end' => 0, 'time_start' => '00:00:00', 'time_end' => '23:59:59')
),
'remarks' => '週六日全時段'
)
);
}
else
{
$xvars = json_decode($jdata, true);
// 篩選繳期名稱
$arr = array();
$arr_list = explode(',', $info_arr['period_list']);
foreach($arr_list as $idx) $arr[$idx] = $xvars['info']['period_name'][$idx];
$xvars['info']['period_name'] = $arr;
// 篩選會員身份
$arr = array();
$arr_list = explode(',', $info_arr['member_attr_list']);
foreach($arr_list as $idx) $arr[$idx] = $xvars['info']['member_attr'][$idx];
$xvars['info']['member_attr'] = $arr;
}
$mem->set('st_info', $info_arr);
$mem->set('info', $xvars['info']);
$mem->set('pt', $xvars['pt']);
trigger_error('st_info: '.print_r($info_arr, true));
trigger_error('xvars: '.print_r($xvars, true));
}
// 顯示場站初始化參數
function show_all_vars($connection)
{
global $info_arr, $xvars;
$connection->send(json_encode($xvars, JSON_UNESCAPED_UNICODE));
}
// 場站初始化參數
function get_var($connection)
{
global $xvars;
$str = gettype($xvars[$_REQUEST['var']]) == 'array' ? json_encode($xvars[$_REQUEST['var']], JSON_UNESCAPED_UNICODE) : $xvars[$_REQUEST['var']];
$connection->send($str);
}
// 顯示場站初始化參數
function set_var($connection)
{
global $xvars;
$xvars[$_REQUEST['var']] = $_REQUEST['val'];
$connection->send('1');
}
// 批次同步資料表至總管理處
function sync_batch($connection)
{
global $query_syncs, $query_sync2hq_ok;
//trigger_error(__FUNCTION__ . '..start..');
$connection->close(); // 先斷線再繼續處理
foreach(explode(',', $_REQUEST['sync_seqnos']) as $st_sync_no)
{
if(empty($st_sync_no)) continue;
$query_syncs->execute(array($st_sync_no));
$rows_syncs = $query_syncs->fetch(PDO::FETCH_ASSOC);
$tx = $rows_syncs;
if(empty($tx)) continue;
$tx['cmd'] = 'sync_st2hq'; // 場站同步至總管理處
$hq_sync_no = worker_tx($tx);
//trigger_error(__FUNCTION__ . '| 1. st_sync_no: ' . $st_sync_no . ', 2. rows_syncs: ' . $rows_syncs . ', 3. hq_sync_no: ' . $hq_sync_no);
// 同步成功, 記錄之 ( note: 總管理處的 hq_sync 記錄完成就視為完成,各場站 sync.synced = 1 )
if ($hq_sync_no > 0)
{
$query_sync2hq_ok->execute(array($hq_sync_no, $st_sync_no));
}
else
{
trigger_error('sync err:'.json_encode($tx, JSON_UNESCAPED_UNICODE)); // TODO: sync 失敗的處理方式
}
}
//trigger_error(__FUNCTION__ . '..end..');
}
// 月租金額計算
function calculate_rents_amt($connection)
{
$_REQUEST['rents_amt1'] = 100;
$_REQUEST['rents_amt2'] = 200;
cross_header();
$connection->send(json_encode($_REQUEST, JSON_UNESCAPED_UNICODE));
}
// worker connect至總管理處
function worker_tx($data)
{
global $curl_ch, $curl_options;
$curl_options[CURLOPT_POSTFIELDS] = $data;
trigger_error('curl:'. print_r($curl_options, true));
curl_setopt_array($curl_ch, $curl_options);
return(curl_exec($curl_ch));
}
// 發生錯誤時集中在此處理
function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
}

+ 38
- 0
coworker/sync_hq_daily.php 파일 보기

@@ -0,0 +1,38 @@
<?php
/*
file: call_sync_daily.php 每日自動呼叫
*/
// 場站共用設定檔
require_once '/home/bigbang/apps/coworker/station.config.php';
define('APP_NAME', 'sync_hq_daily'); // application name
// 發生錯誤時集中在此處理
function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
}
set_error_handler('error_handler', E_ALL);
trigger_error('..start..');
try
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/admins_station.html/do_sync_batch_100");
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POST, FALSE);
$output = curl_exec($ch);
curl_close($ch);
}
catch(Exception $e)
{
trigger_error('ERROR: ' . $e->getMessage());
}
trigger_error('..completed..');

+ 38
- 0
coworker/sync_minutely.php 파일 보기

@@ -0,0 +1,38 @@
<?php
/*
file: sync minutely 自動呼叫
*/
// 場站共用設定檔
require_once '/home/bigbang/apps/coworker/station.config.php';
define('APP_NAME', 'sync_minutely'); // application name
// 發生錯誤時集中在此處理
function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
{
$str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
}
set_error_handler('error_handler', E_ALL);
trigger_error('..start..');
try
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/carpark.html/sync_minutely");
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POST, FALSE);
$output = curl_exec($ch);
curl_close($ch);
}
catch(Exception $e)
{
trigger_error('ERROR: ' . $e->getMessage());
}
trigger_error('..completed..');

+ 342
- 0
models/Acer_service_model.php 파일 보기

@@ -0,0 +1,342 @@
<?php
/*
file: acer_servicemodel.php
*/
class Acer_service_model extends CI_Model
{
var $vars = array();
var $now_str;
function __construct()
{
parent::__construct();
$this->load->database();
$this->now_str = date('Y-m-d H:i:s');
// ACER 連線設定 (測試環境)
//define('ACER_SERVICE_IP', '220.130.199.142');
//define('ACER_SERVICE_PORT', 60833);
// ACER 連線設定 (測試環境 - 現場呼叫)
//define('ACER_SERVICE_IP', '220.130.199.142');
//define('ACER_SERVICE_PORT', 8033);
// ACER 連線設定 (正式環境 - 現場呼叫)
define('ACER_SERVICE_IP', '192.168.10.221');
define('ACER_SERVICE_PORT', 8033);
// 結果代碼
define('ALTOB_RESULT_CODE_SUCCESS', 'OK'); // 成功
define('ALTOB_RESULT_CODE_FAIL', 'GG'); // 失敗
// 錯誤碼
define('ALTOB_ERROR_CODE_NONE', '0000'); // 預設值 (成功帶這個)
define('ALTOB_ERROR_CODE_UNKNOWN_INPUT', '1001'); // 未知的 輸入
define('ALTOB_ERROR_CODE_UNKNOWN_CMD', '1002'); // 未知的 CMD
define('ALTOB_ERROR_CODE_NOT_FOUND', '1003'); // 查無記錄
define('ALTOB_ERROR_CODE_ERROR', '1004'); // 交易失敗
define('ALTOB_ERROR_CODE_UNDEFINED', '9999'); // 未定義的錯誤
define('ALTOB_ERROR_CODE_ACER_RESULT_FAIL', '2001'); // ACER 回傳處理錯誤
}
// acer socket
function acer_socket($in)
{
trigger_error(__FUNCTION__ . "..socket input|{$in}");
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
trigger_error(__FUNCTION__ . "..socket_create() failed: reason: " . socket_strerror(socket_last_error()));
}
$result = socket_connect($socket, ACER_SERVICE_IP, ACER_SERVICE_PORT);
if ($result === false) {
trigger_error(__FUNCTION__ . "..socket_connect() failed.\nReason: ({$result}) " . socket_strerror(socket_last_error($socket)));
return false; // 中斷
}
if(!socket_write($socket, $in, strlen($in)))
{
trigger_error(__FUNCTION__ . '..Write failed..');
}
$out = socket_read($socket, 64);
socket_shutdown($socket);
socket_close($socket);
trigger_error(__FUNCTION__ . "..socket output|{$out}");
return $out;
}
public function init($vars)
{
$this->vars = $vars;
}
// 票卡入場訊號,供 ALTOB 登記
//(傳入:卡號、入場編號、是否月租卡; 回傳:結果代碼、入場編號、錯誤碼)
public function cmd_001($card_no, $cario_no, $card_type)
{
// 票號查詢最近一筆入場資料
$rows_cario = $this->db
->select('cario_no, lpr, in_time, pay_time, out_before_time')
->from('cario')
->where(array(
'in_out' => 'CI', 'err' => 0, 'finished' => 0,
'cario_no' => $cario_no,
'in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 DAY)' => null))
->limit(1)
->get()
->row_array();
trigger_error(__FUNCTION__ . '..cario..' . print_r($rows_cario, true));
$cario_no = 0; // 進出碼
$error_code = ALTOB_ERROR_CODE_NONE; // 錯誤碼
if (!empty($rows_cario['cario_no']))
{
$cario_no = $rows_cario['cario_no'];
// 更新入場資訊
$this->db->where(array('cario_no' => $cario_no))->update('cario', array('remarks' => "{$card_no}"));
if (!$this->db->affected_rows())
{
trigger_error(__FUNCTION__ . '..fail..' . $this->db->last_query());
$error_code = ALTOB_ERROR_CODE_ERROR;
}
}
else
{
// 查無入場記錄
$error_code = ALTOB_ERROR_CODE_NOT_FOUND;
}
$data = array();
$data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
$data['result']['cario_no'] = $cario_no;
$data['result']['error_code'] = $error_code;
return $data;
}
// 票卡離場訊號,供 ALTOB 登記
//(傳入:卡號、繳費時間、是否月租卡; 回傳:結果代碼、入場編號、錯誤碼)
public function cmd_002($card_no, $pay_time, $card_type)
{
// 卡號查詢最近一筆入場資料
$rows_cario = $this->db
->select('cario_no, lpr, in_time, pay_time, out_before_time')
->from('cario')
->where(array(
'in_out' => 'CI', 'err' => 0, 'finished' => 0,
'remarks' => $card_no,
'in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY)' => null))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
trigger_error(__FUNCTION__ . '..cario..' . print_r($rows_cario, true));
$cario_no = 0; // 進出碼
$error_code = ALTOB_ERROR_CODE_NONE; // 錯誤碼
if (!empty($rows_cario['cario_no']))
{
$cario_no = $rows_cario['cario_no'];
// 暫不處理
}
else
{
// 查無入場記錄
$error_code = ALTOB_ERROR_CODE_NOT_FOUND;
}
$data = array();
$data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
$data['result']['cario_no'] = $cario_no;
$data['result']['error_code'] = $error_code;
return $data;
}
// 票號離場訊號,回傳若成功觸發 ACER 開門
// (傳入:6 碼數字; 回傳:結果代碼、入場編號、錯誤碼、離場代碼)
public function cmd_003($ticket_no)
{
// 票號查詢最近一筆入場資料 (只能查 5天 內)
$rows_cario = $this->db
->select('cario_no, payed, in_time, pay_time, out_before_time')
->from('cario')
->where(array(
'ticket_no' => $ticket_no, 'err' => 0,
'in_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY)' => null)
)
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
trigger_error(__FUNCTION__ . '..cario..' . print_r($rows_cario, true));
$cario_no = 0; // 進出碼
$error_code = ALTOB_ERROR_CODE_NONE; // 錯誤碼
$msg_code = 0; // 離場碼
if (!empty($rows_cario['cario_no']))
{
$cario_no = $rows_cario['cario_no'];
if(strtotime($rows_cario['out_before_time']) >= time())
{
if ($rows_cario['payed'])
{
// CO.B.1 臨停車已付款
$msg_code = 6;
}
else
{
// CO.B.2 臨停車未付款
$msg_code = 8;
}
}
else
{
// CO.C.1 其它付款方式
$msg_code = 9;
}
}
else
{
// CO.Z.Z 無入場資料
$cario_no = 0;
$msg_code = 13;
}
$data = array();
$data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
$data['result']['cario_no'] = $cario_no;
$data['result']['error_code'] = $error_code;
$data['result']['msg_code'] = $msg_code;
return $data;
}
// 呼叫 acer (cmd: 101)
// (傳入:入場編號、進場時間、 6 碼數字、車牌號碼、出入口編號; 回傳:結果代碼、入場編號、錯誤碼)
public function cmd_101($cario_no, $in_time, $ticket_no, $lpr, $ivs_no)
{
$seq = '00001';
$cmd = '101';
$cario_no_pad = str_pad($cario_no, 10, '0', STR_PAD_LEFT); // 入場編號: 10 碼 (左邊補 0)
$lpr_pad = str_pad($lpr, 10, '*', STR_PAD_LEFT); // 車牌號碼: 10 碼 (左邊補 *)
$ivs_no_pad = str_pad($ivs_no, 2, '0', STR_PAD_LEFT); // 車道編號: 2 碼 (左邊補 0)
// 建立封包
$packformat = "a10Ca19Ca6Ca10Ca2";
$data = pack($packformat,
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$cario_no_pad, 0x1f, $in_time, 0x1f, $ticket_no, 0x1f, $lpr_pad, 0x1f, $ivs_no_pad
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$in = pack("Ca2Ca5Ca3C{$packformat}CCC",
0x02, // STX:封包起始碼(0x02)
$socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
$seq, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
$cmd, 0x1c, // CmdID:命令ID
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$cario_no_pad, 0x1f, $in_time, 0x1f, $ticket_no, 0x1f, $lpr_pad, 0x1f, $ivs_no_pad,
0x1c,
0x80, // CRC:封包檢查碼
0x03 // ETX:封包結束碼(0x03)
);
// 連線
$out = $this->acer_socket($in);
if(!empty($out))
{
list($front, $seq, $cmd, $data) = explode(chr(28), $out);
list($result_code, $cario_no, $error_code) = explode(chr(31), $data);
trigger_error(__FUNCTION__ . "..socket return explode|{$front}, {$seq}, {$cmd}, {$result_code}, {$cario_no}, {$error_code}");
if(!empty($result_code) && ALTOB_RESULT_CODE_SUCCESS == $result_code)
{
$data = array();
$data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
$data['result']['cario_no'] = $cario_no;
return $data;
}
}
$data = array();
$data['result_code'] = ALTOB_RESULT_CODE_FAIL;
$data['result']['error_code'] = ALTOB_ERROR_CODE_ACER_RESULT_FAIL;
return $data;
}
// 呼叫 acer (cmd: 102)
// (傳入:入場編號、出入口編號、離場代碼; 回傳:結果代碼、入場編號、錯誤碼)
public function cmd_102($cario_no, $ivs_no, $msg_code)
{
$seq = '00001';
$cmd = '102';
$cario_no_pad = str_pad($cario_no, 10, '0', STR_PAD_LEFT); // 入場編號: 10 碼 (左邊補 0)
$ivs_no_pad = str_pad($ivs_no, 2, '0', STR_PAD_LEFT); // 車道編號: 2 碼 (左邊補 0)
$msg_code_pad = str_pad($msg_code, 5, '0', STR_PAD_LEFT); // 離場代碼: 5 碼 (左邊補 0)
// 建立封包
$packformat = "a10Ca2Ca5";
$data = pack($packformat,
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$cario_no_pad, 0x1f, $ivs_no_pad, 0x1f, $msg_code_pad
);
$data_len = strlen($data);
$socket_len = $data_len + 16;
$in = pack("Ca2Ca5Ca3C{$packformat}CCC",
0x02, // STX:封包起始碼(0x02)
$socket_len, 0x1c, // 封包長度:從STX到ETX的位元數
$seq, 0x1c, // 封包流水號:5碼ASCII數字(不足5碼時左補”0”補滿5碼)
$cmd, 0x1c, // CmdID:命令ID
// Data:內容除分隔符號為0x1F,其他全為ASCII碼0x20 ~ 0x7F內
$cario_no_pad, 0x1f, $ivs_no_pad, 0x1f, $msg_code_pad,
0x1c,
0x80, // CRC:封包檢查碼
0x03 // ETX:封包結束碼(0x03)
);
// 連線
$out = $this->acer_socket($in);
if(!empty($out))
{
list($front, $seq, $cmd, $data) = explode(chr(28), $out);
list($result_code, $cario_no, $error_code) = explode(chr(31), $data);
trigger_error(__FUNCTION__ . "..socket return explode|{$front}, {$seq}, {$cmd}, {$result_code}, {$cario_no}, {$error_code}");
if(!empty($result_code) && ALTOB_RESULT_CODE_SUCCESS == $result_code)
{
$data = array();
$data['result_code'] = ALTOB_RESULT_CODE_SUCCESS;
$data['result']['cario_no'] = $cario_no;
return $data;
}
}
$data = array();
$data['result_code'] = ALTOB_RESULT_CODE_FAIL;
$data['result']['error_code'] = ALTOB_ERROR_CODE_ACER_RESULT_FAIL;
return $data;
}
}

+ 896
- 0
models/Admins_model.php 파일 보기

@@ -0,0 +1,896 @@
<?php
/*
file: Admins_model.php
*/
class Admins_model extends CI_Model
{
var $vars = array();
function __construct()
{
parent::__construct();
$this->load->database();
$this->now_str = date('Y-m-d H:i:s');
$this->default_valid_time = date('Y-m-d H:i:s', strtotime("{$this->now_str} + 2 days")); // 2016/12/15 新增有效期限 (預設為兩天)
}
public function init($vars)
{
$this->vars = $vars;
}
// 付款
public function login_verify($login_name, $login_pswd)
{
$rows = $this->db->select('count(*) as ok')
->from('staffs')
->where(array('login_name' => $login_name, 'pswd' => md5($login_pswd)))
->get()
->row_array();
return $rows['ok'];
}
// 讀出各初始值至web
public function get_init_vars()
{
$st_info = $this->vars['mcache']->get('st_info');
// 路徑初始值
$str = "var APP_URL = '". APP_URL . "';\n".
"var WEB_LIB = '" . WEB_LIB . "';\n".
"var BOOTSTRAPS = '" . BOOTSTRAPS . "';\n".
"var WEB_SERVICE = '" . WEB_SERVICE . "';\n".
"var station_no ={$st_info['station_no']};\n".
"var company_no = {$st_info['company_no']};\n".
"var xvars = new Array();\n".
"xvars['ck'] = 'NOLOGIN';\n";
// 讀出場站資訊
$str .= "var st = new Array();\n";
$str .= "st[" . STATION_NO . "]=\"" . STATION_NAME . "\";\n";
/*
$results = $this->db->select('station_no, short_name')
->from('stations')
->order_by('station_no', 'asc')
->get()
->result_array();
$str .= "var st = new Array();\n";
foreach($results as $rows)
{
$str .= "st[{$rows['station_no']}]=\"{$rows['short_name']}\";\n";
}
*/
// 讀出時段表資訊
$str .= "var pt = new Array();\n"; // park_time
foreach($this->vars['mcache']->get('pt') as $key => $rows)
{
$str .= "pt['{$key}']={'seqno':{$rows['seqno']},'remarks':'{$rows['remarks']}'};\n";
}
/*
// 讀取繳期名稱
$rows = $this->db->select('period_name')
->from('info')
->where('seqno', 1)
->get()
->row_array();
$str .= "var period_name=Array();\nperiod_name={$rows['period_name']};\n";
*/
// 篩選會員身份及繳期資訊
$info = $this->vars['mcache']->get('info');
$str .= "var period_name=Array();\n";
foreach($info['period_name'] as $idx => $rows)
{
$str .= "period_name[{$idx}]=\"{$rows}\";\n";
}
$str .= "var mem_attr = new Array();\n";
foreach($info['member_attr'] as $idx => $rows)
{
$str .= "mem_attr[{$idx}]=\"{$rows}\";\n";
}
return $str;
}
/*
// 停車時段資訊
public function park_time()
{
$data = array();
$idx = 0;
// $results = $this->db->select('time_id, seqno, park_type, week_start, week_end, daytime_start, daytime_end, remarks')
$results = $this->db->select('time_id, seqno, timex, remarks')
->from('park_time')
->order_by('seqno', 'asc')
->get()
->result_array();
foreach($results as $rows)
{
$data[$idx] = array
(
'time_id' => $rows['time_id'],
'seqno' => $rows['time_id'],
'remarks' => $rows['remarks']
);
++$idx;
}
return $results;
}
// 停車時段資訊單筆刪除
public function park_time_delete($time_id)
{
$this->db->delete('park_time', array('time_id' => $time_id));
return true;
}
*/
// 會員清單
public function member_query_all()
{
$sql = "
SELECT
MIN(CONCAT(member_tx.tx_no, member_tx.verify_state)) as tx_order,
members.member_no,
members.lpr,
members.etag,
members.member_name,
members.mobile_no,
members.start_date,
members.end_date,
members.fee_period,
members.member_attr,
members.suspended,
members.contract_no,
members.amt,
member_tx.tx_no,
member_tx.verify_state,
member_tx.valid_time,
member_tx.remarks
FROM member_tx
LEFT JOIN members ON member_tx.member_no = members.member_no
WHERE
members.member_no IS NOT NULL
GROUP BY member_tx.member_no
ORDER BY members.lpr ASC
";
$results = $this->db->query($sql)->result_array();
return $results;
}
// 待審核清單
public function member_tx_check()
{
$sql = "
SELECT
members.lpr as current_lpr,
member_tx.lpr,
member_tx.tx_no,
member_tx.station_no,
member_tx.member_no,
member_tx.fee_period,
member_tx.fee_period_last,
member_tx.amt1,
member_tx.amt,
member_tx.amt_last,
member_tx.deposit,
date_format(member_tx.start_date,'%Y-%m-%d') as start_date,
date_format(member_tx.end_date,'%Y-%m-%d') as end_date,
date_format(member_tx.start_date_last,'%Y-%m-%d') as start_date_last,
date_format(member_tx.end_date_last,'%Y-%m-%d') as end_date_last,
member_tx.member_company_no,
member_tx.company_no,
member_tx.acc_date,
member_tx.invoice_no,
member_tx.invoice_amt,
member_tx.invoice_track,
member_tx.invoice_time,
member_tx.invoice_type,
member_tx.verify_state,
member_tx.valid_time,
member_tx.remarks
FROM member_tx
LEFT JOIN members ON (member_tx.member_no = members.member_no AND members.station_no = member_tx.station_no)
WHERE member_tx.verify_state != 1
ORDER BY member_tx.valid_time ASC
";
$results = $this->db->query($sql)->result_array();
return $results;
}
// 會員查詢
public function member_query($station_no, $q_item, $q_str)
{
$where_station = $station_no == 0 ? '' : " station_no = {$station_no} and "; // 如為0, 則全部塲站讀取
switch($q_item)
{
case 'end_date':
$items = "{$q_item} <=";
$q_str .= ' 23:59:59';
break;
case 'lpr':
$items = "{$q_item} like ";
$q_str = strtoupper($q_str).'%';
break;
default:
$items = "{$q_item} like ";
$q_str .= '%';
break;
}
$sql = "select
station_no,
member_no,
lpr,
member_name,
mobile_no,
date_format(demonth_start_date,'%Y-%m-%d') as demonth_start_date,
date_format(demonth_end_date,'%Y-%m-%d') as demonth_end_date,
date_format(start_date,'%Y-%m-%d') as start_date,
date_format(end_date,'%Y-%m-%d') as end_date,
date_format(rent_start_date,'%Y-%m-%d') as rent_start_date,
contract_no,
coalesce(etag, '') as etag,
fee_period1,
fee_period,
amt1,
amt,
if(member_company_no > 0, member_company_no, '') as member_company_no,
if(company_no > 0, company_no, '') as company_no,
coalesce(member_attr, 1) as member_attr,
deposit,
park_time,
coalesce(member_id, '') as member_id,
coalesce(tel_o, '') as tel_o,
coalesce(tel_h, '') as tel_h,
coalesce(addr, '') as addr,
suspended
from members
where {$where_station} {$items} '{$q_str}'";
$results = $this->db->query($sql)->result_array();
return $results;
}
// 交易查詢
public function member_tx_query($station_no, $member_no)
{
$sql = "select
tx_no, station_no,
member_no,
lpr,
fee_period,
fee_period_last,
amt1,
amt,
amt_last,
deposit,
date_format(start_date,'%Y-%m-%d') as start_date,
date_format(end_date,'%Y-%m-%d') as end_date,
date_format(start_date_last,'%Y-%m-%d') as start_date_last,
date_format(end_date_last,'%Y-%m-%d') as end_date_last,
member_company_no,
company_no,
acc_date,
invoice_no,
invoice_amt,
invoice_track,
invoice_time,
invoice_type,
verify_state,
valid_time,
remarks
from member_tx
where station_no = {$station_no} and member_no = {$member_no}
order by tx_no desc";
$results = $this->db->query($sql)->result_array();
return $results;
}
// 審核完成
public function member_tx_confirmed($parms)
{
$this->try_sync_batch($parms['station_no']); // 同步未同步記錄
$altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
if($altob_admin_submit !== $this->gen_admin_ck($parms['station_no']))
{
trigger_error(__FUNCTION__ . '..altob_admin_submit error..' . print_r($parms, true));
return 'admin_error'; // 中斷
}
$data_tx = array('verify_state' => $parms['verify_state'], 'valid_time' => $parms['valid_time'], 'remarks' => $parms['remarks']);
// [A.開始]
$this->db->trans_start();
$this->db->update('member_tx', $data_tx, array('station_no' => $parms['station_no'], 'tx_no' => $parms['tx_no'])); // t1. 更新 member_tx.verify_state, member_tx.valid_time, member_tx.remarks
// [B.建立同步檔]
$sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx', $parms['tx_no'], $data_tx); // t2. 準備同步檔 (member_tx)
// [C.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . '|'.print_r($data_tx, true) . '..trans_error..');
return 'fail'; // 中斷
}
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
return 'ok';
}
// 刪除月租會員
public function member_delete($station_no, $member_no)
{
$this->try_sync_batch($station_no); // 同步未同步記錄
// [A.開始]
$this->db->trans_start();
$this->db->delete('members', array('station_no' => $station_no, 'member_no' => $member_no, 'suspended' => 0)); // t1. 刪除 members
$this->db->delete('member_car', array('station_no' => $station_no, 'member_no' => $member_no)); // t2. 刪除 member_car
// [B.建立同步檔]
$sync_seqnos = $this->prepare_sync2hq('D', $station_no, 'members', $member_no, array()); // t3. 準備同步檔 (members)
// [C.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . ": {$station_no}, {$member_no}, trans_error..");
return 'trans_error';
}
// 同步至總管理處
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
return 'ok';
}
// 月租會員加入
public function member_add($data)
{
$data['lpr'] = preg_replace('/\s+/', '', $data['lpr']); // 移除空白
$check_member_no = $data['member_no'];
$station_no = $data['station_no'];
$tx_no = 0;
$this->try_sync_batch($station_no); // 同步未同步記錄
// 會員車輛基本資料檔
$start_date = (empty($data['demonth_start_date']) ? $data['start_date'] : $data['demonth_start_date']);
$data['rent_start_date'] = $data['start_date'];
$data['rent_end_date'] = $data['end_date'];
$data['start_date'] = "{$start_date} 00:00:00";
$data['end_date'] = "{$data['end_date']} 23:59:59";
$old_lpr = $data['old_lpr'];
unset($data['old_lpr']);
$data_car = array
(
'lpr' => $data['lpr'],
'lpr_correct' => $data['lpr'],
'etag' => $data['etag'],
'station_no' => $station_no,
'start_time' => $data['start_date'],
'end_time' => $data['end_date']
);
if ($check_member_no == 0) // 新增一筆會員資料
{
unset($data['member_no']);
$data['payed_date'] = substr($this->now_str, 0, 10);
$data['login_id'] = $data['lpr'];
$data['passwd'] = $data['lpr'];
$action_code = 'A';
// [A.開始]
$this->db->trans_start();
$this->db->insert('members', $data); // t1 新增 members
$members_insert_id = $this->db->insert_id();
$data_car['member_no'] = $members_insert_id; // t2. 新增 member_car
$this->db->insert('member_car', $data_car);
$data['member_no'] = $members_insert_id;
$data_bill = array(
'member_no' => $members_insert_id, // 會員編號
'station_no' => $station_no, // 場站編號
'lpr' => $data['lpr'], // 車牌號碼
'amt_accrued' => $data['amt_accrued'], // 應收租金
'amt_tot' => $data['amt_tot'], // 實收租金
'deposit' => $data['deposit'], // 押金
'amt' => $data['amt'], // 本期租金
'fee_period' => $data['fee_period'], // 本期繳期
'start_date' => $data['rent_start_date'], // 本期開始日
'end_date' => $data['rent_end_date'], // 本期結束日
'amt1' => $data['amt1'], // 首期租金
'amt_last' => $data['amt1'], // 上期租金
'fee_period_last' => $data['fee_period1'], // 上期繳期
'start_date_last' => $data['demonth_start_date'], // 上期開始日
'end_date_last' => $data['demonth_end_date'] // 上期結束日
);
$this->db->insert('member_bill', $data_bill); // t3 新增 member_bill
$bill_no = $this->db->insert_id(); // 帳單序號
$data_tx = array(
'bill_no' => $bill_no, // 帳單序號
'member_no' => $members_insert_id, // 會員編號
'station_no' => $station_no, // 場站編號
'sync_no' => 0, // 預設同步編號
'lpr' => $data['lpr'], // 車牌號碼
'amt_accrued' => $data['amt_accrued'], // 應收租金
'amt_tot' => $data['amt_tot'], // 實收租金
'deposit' => $data['deposit'], // 押金
'amt' => $data['amt'], // 本期租金
// todo: 2016/12/23 只要超過季繳金額就拆開, 後續再由待開發票開立
'fee_period' => $data['fee_period'], // 本期繳期
'start_date' => $data['rent_start_date'], // 本期開始日
'end_date' => $data['rent_end_date'], // 本期結束日
'amt1' => $data['amt1'], // 首期租金
'amt_last' => $data['amt1'], // 上期租金
'fee_period_last' => $data['fee_period1'], // 上期繳期
'start_date_last' => $data['demonth_start_date'], // 上期開始日
'end_date_last' => $data['demonth_end_date'], // 上期結束日
'member_company_no' => $data['member_company_no'], // 買方統編
'company_no' => $data['company_no'], // 賣方統編
'acc_date' => $data['payed_date'], // 入帳日(暫定)
'valid_time' => $this->default_valid_time // 有效期限
);
$this->db->insert('member_tx', $data_tx); // t4 新增 member_tx
$tx_no = $this->db->insert_id(); // 交易序號
$data_tx['tx_no'] = $tx_no;
// [B.建立同步檔]
$sync_seqnos = $this->prepare_sync2hq($action_code, $station_no, 'members', $members_insert_id, $data); // t5 準備同步檔 (members)
$sync_seqnos .= ',' . $this->prepare_sync2hq($action_code, $station_no, 'member_bill', $bill_no, $data_bill); // t6 準備同步檔 (member_bill)
$sync_seqnos .= ',' . $this->prepare_sync2hq($action_code, $station_no, 'member_tx', $tx_no, $data_tx); // t7 準備同步檔 (member_tx)
// [C.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . '..trans_error..' . print_r($data, true));
return 'trans_error';
}
// 同步至總管理處
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
}
else
{
$altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
if($altob_admin_submit == $this->gen_admin_ck($station_no))
{
trigger_error("admin: " + $altob_admin_submit);
//unset($data['contract_no']); // 合約號
//unset($data['park_time']); // 停車時段
unset($data['rent_start_date']);
unset($data['rent_end_date']);
unset($data['start_date']);
unset($data['end_date']);
unset($data['demonth_start_date']);
unset($data['demonth_end_date']);
unset($data['member_attr']);
unset($data['deposit']);
unset($data['amt_tot']);
unset($data['amt_accrued']);
unset($data['fee_period1']);
unset($data['amt1']);
//unset($data['fee_period']); // 例行繳期
//unset($data['amt']); // 例行租金
}
else
{
// 一般情況下, 時段與費率都不能在這個流程修改
//unset($data['contract_no']); // 合約號
unset($data['park_time']);
unset($data['rent_start_date']);
unset($data['rent_end_date']);
unset($data['start_date']);
unset($data['end_date']);
unset($data['demonth_start_date']);
unset($data['demonth_end_date']);
unset($data['member_attr']);
unset($data['deposit']);
unset($data['amt_tot']);
unset($data['amt_accrued']);
unset($data['fee_period1']);
unset($data['amt1']);
unset($data['fee_period']);
unset($data['amt']);
}
$action_code = 'U';
// [A.開始]
$this->db->trans_start();
$this->db->update('members', $data, array('station_no' => $station_no, 'member_no' => $check_member_no)); // t1. 更新 members
// 沒有異動到車牌, 使用update, 否則重建一筆
if ($old_lpr == $data['lpr']) // t2. 更新 member_car
{
unset($data_car['lpr']);
unset($data_car['lpr_correct']);
$this->db->update('member_car', $data_car, array('station_no' => $station_no, 'member_no' => $check_member_no));
}
else
{
$this->db->delete('member_car', array('station_no' => $station_no, 'member_no' => $check_member_no));
$data_car['member_no'] = $check_member_no;
$this->db->insert('member_car', $data_car);
}
// [B.建立同步檔]
$sync_seqnos = $this->prepare_sync2hq($action_code, $station_no, 'members', $check_member_no, $data); // t3. 準備同步檔 (members)
// [C.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . '..trans_error..' . print_r($data, true));
return 'trans_error';
}
// 同步至總管理處
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
}
return array(
'station_no' => $station_no,
'company_no' => $data['company_no'],
'member_no' => $data['member_no'],
'start_date' => $start_date,
'msg' => 'ok',
'action_code' => $action_code,
'tx_no' => $tx_no);
}
// 查詢車牌是否重複
public function check_lpr($lpr)
{
$rows = $this->db->select('count(*) as counts')
->from('members')
->where(array('lpr' => $lpr))
->get()
->row_array();
return $rows['counts'];
}
// 取得交易發票
public function get_tx_invoice_no($tx_no)
{
$rows = $this->db->select('invoice_no')
->from('member_tx')
->where(array('tx_no' => $tx_no))
->get()
->row_array();
return $rows['invoice_no'];
}
// 更新月租發票記錄
public function set_tx_invoice_no($parms)
{
$data = array
(
'member_company_no' => $parms['member_company_no'],
'company_no' => $parms['company_no'],
'invoice_track' => $parms['invoice_track'],
'invoice_no' => $parms['invoice_no'],
'invoice_amt' => $parms['invoice_amt'],
'invoice_time' => $parms['invoice_time']
);
if(array_key_exists('invoice_type', $parms))
{
$data['invoice_type'] = $parms['invoice_type']; // 發票種類
}
// [A.開始]
$this->db->trans_start();
$this->db->update('member_tx', $data, array('station_no' => $parms['station_no'], 'tx_no' => $parms['tx_no'])); // t1. 更新 member_tx
// [B.建立同步檔]
$sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'member_tx', $parms['tx_no'], $data); // t2. 準備同步檔
// [C.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . '|'.print_r($data, true) . '..trans_error..');
return 'fail'; // 中斷
}
// 同步至總管理處
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
return 'ok';
}
// 首期月租付款交易
public function first_rents_payment($parms)
{
$this->try_sync_batch($parms['station_no']); // 同步未同步記錄
// 確認交易記錄
$rows = $this->db->select('count(*) as counts')
->from('member_tx')
->where(array('tx_no' => $parms['tx_no'],
'station_no' => $parms['station_no'], 'member_no' => $parms['member_no'],
'amt' => $parms['amt'], 'amt1' => $parms['amt1']))
->get()
->row_array();
if(empty($rows) || $rows['counts'] != 1)
{
trigger_error(__FUNCTION__ . '..tx gg..' . print_r($parms, true));
return 'tx_error'; // 中斷
}
// 印發票
$parms['invoice_amt'] = $parms['amt'] + $parms['amt1']; // 例行租金 + 首期租金
if(array_key_exists('invoice_track', $parms) && array_key_exists('invoice_no', $parms))
{
$parms['invoice_time'] = date('Y-m-d H:i:s'); // 目前時間
}
else
{
$invoice_result = $this->print_invoice($parms);
if(!empty($invoice_result) && array_key_exists('einvoice_no', $invoice_result))
{
$parms['invoice_track'] = $invoice_result['einvoice_track']; // 發票字軌
$parms['invoice_no'] = $invoice_result['einvoice_no']; // 發票號碼
$parms['invoice_time'] = date('Y-m-d H:i:s'); // 目前時間
}
}
if(empty($parms['invoice_no']) || empty($parms['invoice_track']))
{
trigger_error(__FUNCTION__ . '..invoice gg..' . print_r($parms, true));
return 'invoice_fail'; // 中斷
}
// 更新月租發票記錄
echo $this->set_tx_invoice_no($parms);
}
// 新增月租付款交易
public function rents_payment($parms)
{
$this->try_sync_batch($parms['station_no']); // 同步未同步記錄
//$parms['start_date'] = $parms['start_date_last'];
// 印發票
$parms['invoice_amt'] = $parms['amt']; // 例行租金
if(array_key_exists('invoice_track', $parms) && array_key_exists('invoice_no', $parms))
{
$parms['invoice_time'] = date('Y-m-d H:i:s'); // 目前時間
}
else
{
$invoice_result = $this->print_invoice($parms);
if(!empty($invoice_result) && array_key_exists('einvoice_no', $invoice_result))
{
$parms['invoice_track'] = $invoice_result['einvoice_track']; // 發票字軌
$parms['invoice_no'] = $invoice_result['einvoice_no']; // 發票號碼
$parms['invoice_time'] = date('Y-m-d H:i:s'); // 目前時間
}
if(empty($parms['invoice_no']) || empty($parms['invoice_track']))
{
trigger_error(__FUNCTION__ . '..invoice gg..' . print_r($parms, true));
//return 'invoice_fail';
}
}
$parms['sync_no'] = 0; // 預設同步編號
$parms['fee_period_last'] = $parms['fee_period']; // 上期繳期
$parms['start_date'] = date('Y-m-d', strtotime("{$parms['end_date_last']} first day of next month")); // 本期開始日:上期結束日之次月首日
$parms['acc_date'] = date('Y-m-d'); // 入帳日(暫定)
$parms['valid_time'] = $this->default_valid_time; // 有效期限
// [A.開始]
$this->db->trans_start();
$this->db->insert('member_tx', $parms); // t1. 新增 member_tx
$tx_no = $this->db->insert_id(); // 交易序號
$data = $parms;
$data['tx_no'] = $tx_no;
$data_member = array(
'fee_period' => $parms['fee_period'],
'payed_date' => substr($parms['invoice_time'], 0, 10),
'start_date' => "{$parms['start_date_last']} 00:00:00", // 開始日:由上期繼續延續下去
'end_date' => "{$parms['end_date']} 23:59:59" // 結束日
);
$this->db->update('members', $data_member, array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t2. 更新 members
$this->db->update('member_car', // t5. 更新 member_car
array('start_time' => "{$data_member['start_date']} 00:00:00", 'end_time' => "{$data_member['end_date']} 23:59:59"),
array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no']));
// [B.準備同步檔]
$sync_seqnos = $this->prepare_sync2hq('A', $parms['station_no'], 'member_tx', $tx_no, $data); // t2. 準備同步檔
$sync_seqnos .= ',' . $this->prepare_sync2hq('U', $parms['station_no'], 'members', $parms['member_no'], $data_member); // t4. 準備同步檔
// [c.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . '|'.print_r($data, true) . '..trans_error..');
return 'fail'; // 中斷
}
// 同步至總管理處
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
return 'ok';
}
// 停權或啟動
public function suspended($parms)
{
$this->try_sync_batch($parms['station_no']); // 同步未同步記錄
$altob_admin_submit = $this->input->post('altob_admin_submit', true); // 取得 admin 參數
if($altob_admin_submit !== $this->gen_admin_ck($parms['station_no']))
{
trigger_error(__FUNCTION__ . '..altob_admin_submit error..' . print_r($parms, true));
return 'admin_error'; // 中斷
}
$data = array('suspended' => $parms['suspended']);
// [A.開始]
$this->db->trans_start();
$this->db->update('members', $data, array('station_no' => $parms['station_no'], 'member_no' => $parms['member_no'])); // t1. 更新 member.suspended
// [B.準備同步檔]
$sync_seqnos = $this->prepare_sync2hq('U', $parms['station_no'], 'members', $parms['member_no'], $data); // t2. 準備同步檔
// [C.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . '|'.print_r($data, true) . '..trans_error..');
return 'fail'; // 中斷
}
// 同步至總管理處
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
return 'ok';
}
// 同步未同步記錄
public function try_sync_batch($station_no, $limit=5)
{
$sql = "select st_sync_no
from syncs
where synced = 0 and erred = 0 and station_no = {$station_no}
order by st_sync_no ASC
limit {$limit}";
$results = $this->db->query($sql)->result_array();
if(empty($results)) return false; // do nothing
$sync_seqnos = '';
foreach($results as $rows)
{
$sync_seqnos .= ',' . $rows['st_sync_no'];
}
$sync_seqnos = ltrim($sync_seqnos, ',');
trigger_error(__FUNCTION__ . '|' . $sync_seqnos);
// 同步至總管理處
$this->worker_tx('sync_batch', array('sync_seqnos' => $sync_seqnos));
}
// 同步至總公司
function prepare_sync2hq($act, $station_no, $st_tname, $st_seqno, $data)
{
$data_syncs = array
(
'station_no' => $station_no,
'synced' => 0, // 尚未同步
'erred' => 0,
'act' => $act, // A:新增, U:修改, D:刪除
'hq_tname' => 'hq_'.$st_tname,
'st_tname' => $st_tname, // 場站資料表
'st_seqno' => $st_seqno, // 場站交易序號
'sync_data' => json_encode($data, JSON_UNESCAPED_UNICODE)
);
$this->db->insert('syncs', $data_syncs);
return $this->db->insert_id();
}
// curl送收資料
function worker_tx($cmd, $data)
{
try
{
$ch = curl_init();
$curl_options = array
(
CURLOPT_URL => "http://localhost:60133/?cmd={$cmd}",
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1, // 返回值不顯示, 只做變數用
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $data
);
curl_setopt_array($ch, $curl_options);
curl_exec($ch);
curl_close($ch);
}
catch (Exception $e)
{
trigger_error("{$cmd} error: ".$e->getMessage());
}
}
// 管理員參數
function gen_admin_ck($station_no)
{
return md5(date("m \a\l\t\o\b d").$station_no.date("i \z\z\z H"));
}
// 印發票
public function print_invoice($parms)
{
$result = array();
try
{
// 印發票
$ch = curl_init();
$curl_options = array
(
CURLOPT_URL => "http://localhost:60134/",
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_CONNECTTIMEOUT => 2,
CURLOPT_TIMEOUT => 2,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => array(
'cmd' => 'printInvoice',
'company_no' => $parms['company_no'],
'vCUS_COMP_CODE'=> $parms['member_company_no'],
'vAmount' => $parms['invoice_amt'],
'vPLU_MEMO' => 'parking:50:3',
'vTAIL_MESSAGE' => 'Rental'
)
);
curl_setopt_array($ch, $curl_options);
$ch_response = curl_exec($ch);
trigger_error(__FUNCTION__ . '|' . print_r($ch_response, true));
curl_close($ch);
$result = json_decode($ch_response, true);
}
catch (Exception $e)
{
trigger_error(__FUNCTION__ .$e->getMessage());
}
//測試用
//$result['einvoice_track'] = 'AB'; // 發票字軌
//$result['einvoice_no'] = '12345678'; // 發票號碼
return $result;
}
}

+ 3041
- 0
models/Admins_station_model.php
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 1606
- 0
models/Allpa_service_model.php
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 1058
- 0
models/Allpay_invoice_model.php
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 20
- 0
models/Allpay_payment_model.php 파일 보기

@@ -0,0 +1,20 @@
<?php
/*
file: Allpay_payment_model.php 付費系統 (歐付寶)
*/
class Allpay_payment_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
}
// 記錄 (歐付寶付費)
public function create_allpay_feedback_log($data)
{
$this->db->insert('allpay_feedback_log', $data);
return true;
}
}

+ 596
- 0
models/Carpark_model.php 파일 보기

@@ -0,0 +1,596 @@
<?php
/*
file: carpark_model.php 停車管理系統
*/
class Carpark_model extends CI_Model
{
var $vars = array();
function __construct()
{
parent::__construct();
$this->load->database();
}
public function init($vars)
{
$this->vars = $vars;
}
// 月租會員加入
public function member_add($data)
{
// 會員車輛基本資料檔
// $data['start_date'] = "{$data['start_date']} 00:00:00";
// $data['end_date'] = "{$data['end_date']} 23:59:59";
$old_lpr = $data['old_lpr'];
unset($data['old_lpr']);
$data_car = array
(
'lpr' => $data['lpr'],
'lpr_correct' => $data['lpr'],
'etag' => $data['etag'],
'station_no' => $data['station_no'],
'start_time' => $data['start_date'],
'end_time' => $data['end_date']
);
$check_member_no = $data['member_no'];
unset($data['member_no']);
trigger_error("members:".print_r($data, true)."car:".print_r($data_car, true));
if ($check_member_no == 0) // 新增一筆會員資料
{
$this->db->insert('members', $data);
$data_car['member_no'] = $this->db->insert_id();
$this->db->insert('member_car', $data_car);
}
else // update會員資料
{
$this->db->update('members', $data, array('member_no' => $check_member_no));
if ($old_lpr == $data['lpr']) // 沒有異動到車牌, 使用update, 否則重建一筆
{
unset($data_car['lpr']);
unset($data_car['lpr_correct']);
$this->db->update('member_car', $data_car, array('member_no' => $check_member_no));
}
else
{
$this->db->delete('member_car', array('member_no' => $check_member_no));
$data_car['member_no'] = $check_member_no;
$this->db->insert('member_car', $data_car);
}
}
return true;
}
// 查詢車牌是否重複
public function check_lpr($lpr)
{
$rows = $this->db->select('count(*) as counts')
->from('members')
->where(array('lpr' => $lpr))
->get()
->row_array();
return $rows['counts'];
}
// 月租會員查詢
public function member_query()
{
$results = $this->db->select('member_no, lpr, etag, member_name, mobile_no, start_date, end_date, contract_no, amt, member_id, tel_h, tel_o, addr, valid_time, station_no')
->from('members')
->order_by('station_no, lpr', 'asc')
->get()
->result_array();
return $results;
}
// 刪除月租會員
public function member_delete($member_no)
{
$this->db->delete('members', array('member_no' => $member_no));
$this->db->delete('member_car', array('member_no' => $member_no));
return true;
}
// 進出場現況表
public function cario_list()
{
/*
$data_cario = $this->db
->select('c.cario_no, c.in_out, in_lane, out_lane, c.in_time, c.out_time, c.minutes, c.obj_id as lpr, c.etag, c.in_pic_name, c.out_pic_name, m.member_name as owner')
->from('cario c')
->join('members m', 'c.member_no = m.member_no', 'left')
->where(array('c.err' => 0))
->order_by('c.update_time', 'desc')
->limit(10)
->get()
->result_array();
*/
$sql = '(select c.cario_no, c.in_out, in_lane, out_lane, c.in_time, c.out_time, c.minutes, c.obj_id as lpr, c.etag, c.in_pic_name, c.out_pic_name, m.member_name as owner, c.in_time as time_order
from cario c left join members m on c.obj_id = m.lpr
where c.err = 0 and c.out_time is null)
union
(select c.cario_no, c.in_out, in_lane, out_lane, c.in_time, c.out_time, c.minutes, c.obj_id as lpr, c.etag, c.in_pic_name, c.out_pic_name, m.member_name as owner, c.out_time as time_order
from cario c left join members m on c.obj_id = m.lpr
where c.err = 0 and c.out_time is not null)
order by time_order desc limit 10;';
$data_cario = $this->db->query($sql)->result_array();
// $lane_arr = array(0 => '入1', 1 => '入2', 3 => '出3', 3 => '出4');
$idx = 0;
foreach($data_cario as $rows)
{
++$rows['in_lane'];
++$rows['out_lane'];
//$lane_no = $rows['in_out'] == 'CI' ? "入{$rows['in_lane']}" : "入{$rows['in_lane']} -> 出{$rows['out_lane']}";
$lane_no = empty($rows['out_time']) ? "入{$rows['in_lane']}" : "入{$rows['in_lane']} -> 出{$rows['out_lane']}"; // 2016/08/22 有離場時間就顯示
$pic_name = str_replace('.jpg', '', empty($rows['out_pic_name']) ? $rows['in_pic_name'] : $rows['out_pic_name']);
$arr = explode('-', $pic_name);
$pic_path = APP_URL.'pics/'.substr($arr[7], 0, 8).'/'.$pic_name;
$data[$idx] = array
(
// 'io_name' => $io_name[$rows['in_out']],
'io_name' => $lane_no,
'lpr' => $rows['lpr'],
// 'etag' => $rows['etag'],
'etag' => $rows['etag'],
'owner' => $rows['owner'],
'io_time' => empty($rows['out_time']) ? $rows['in_time'] : "{$rows['in_time']}(入)<br>{$rows['out_time']}(出)<br>{$rows['minutes']}分(停留時間)",
'pic_name' => $pic_path
);
++$idx;
}
return $data;
}
// 模糊比對
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 carin_lpr_query($word)
{
// updated 2016/09/09 fuzzy search
if(empty($word) || strlen($word) < 4 || strlen($word) > 10)
{
return array();
}
$fuzzy_statement = $this->getLevenshteinSQLStatement($word, 'c.obj_id');
trigger_error("模糊比對 {$word} where: {$fuzzy_statement}");
$sql = "SELECT c.cario_no, c.in_out, in_lane, out_lane, c.in_time, c.out_time, c.minutes, c.obj_id as lpr, c.etag, c.in_pic_name, c.out_pic_name, m.member_name as owner
FROM cario c
LEFT JOIN members m ON c.obj_id = m.lpr
WHERE {$fuzzy_statement} AND c.err = 0 AND c.obj_type = 1
ORDER BY c.update_time DESC
LIMIT 50";
$data_cario = $this->db->query($sql)->result_array();
/*
$data_cario = $this->db
->select('c.cario_no, c.in_out, in_lane, out_lane, c.in_time, c.out_time, c.minutes, c.obj_id as lpr, c.etag, c.in_pic_name, c.out_pic_name, m.member_name as owner')
->from('cario c')
->join('members m', 'c.member_no = m.member_no', 'left')
->where(array('c.obj_type' => 1, 'obj_id' => $lpr))
->order_by('c.update_time', 'desc')
->get()
->result_array();
*/
$data = array();
$idx = 0;
foreach($data_cario as $rows)
{
++$rows['in_lane'];
++$rows['out_lane'];
$lane_no = empty($rows['out_time']) ? "入{$rows['in_lane']}" : "入{$rows['in_lane']} -> 出{$rows['out_lane']}";
$io_time = empty($rows['out_time']) ? $rows['in_time'] : "{$rows['in_time']}(入)<br>{$rows['out_time']}(出)<br>{$rows['minutes']}分(停留時間)";
$pic_name = str_replace('.jpg', '', empty($rows['out_pic_name']) ? $rows['in_pic_name'] : $rows['out_pic_name']);
$arr = explode('-', $pic_name);
$pic_path = APP_URL.'pics/'.substr($arr[7], 0, 8).'/'.$pic_name;
$data[$idx++] = array
(
'io_name' => $lane_no,
'lpr' => $rows['lpr'],
'etag' => $rows['etag'],
'owner' => empty($rows['owner']) ? '' : $rows['owner'],
'io_time' => $io_time,
'pic_name' => $pic_path
);
}
return $data;
}
// 車號入場查詢
public function carin_time_query($time_query, $minutes_range)
{
$curr_time = date('Y-m-d H:i:s');
$start_time = date('Y-m-d H:i:s', strtotime("{$time_query} - {$minutes_range} minutes"));
$end_time = date('Y-m-d H:i:s', strtotime("{$time_query} + {$minutes_range} minutes"));
$data_cario = $this->db
->select('c.cario_no, c.in_out, in_lane, out_lane, c.in_time, c.out_time, c.minutes, c.obj_id as lpr, c.etag, c.in_pic_name, c.out_pic_name, m.member_name as owner')
->from('cario c')
->join('members m', 'c.obj_id = m.lpr', 'left')
->where(array('c.obj_type' => 1, 'c.in_time >=' => $start_time, 'c.in_time <=' => $end_time))
->order_by('c.update_time', 'desc')
->get()
->result_array();
$data = array();
$idx = 0;
foreach($data_cario as $rows)
{
++$rows['in_lane'];
++$rows['out_lane'];
$lane_no = empty($rows['out_time']) ? "入{$rows['in_lane']}" : "入{$rows['in_lane']} -> 出{$rows['out_lane']}";
$io_time = empty($rows['out_time']) ? $rows['in_time'] : "{$rows['in_time']}(入)<br>{$rows['out_time']}(出)<br>{$rows['minutes']}分(停留時間)";
$pic_name = str_replace('.jpg', '', empty($rows['out_pic_name']) ? $rows['in_pic_name'] : $rows['out_pic_name']);
$arr = explode('-', $pic_name);
$pic_path = APP_URL.'pics/'.substr($arr[7], 0, 8).'/'.$pic_name;
$data[$idx++] = array
(
'io_name' => $lane_no,
'lpr' => $rows['lpr'],
'etag' => $rows['etag'],
'owner' => empty($rows['owner']) ? '' : $rows['owner'],
'io_time' => $io_time,
'pic_name' => $pic_path
);
}
return $data;
}
// 時間長度轉成日時分秒
public function time2str($d1, $d2)
{
$time = strtotime($d2) - strtotime($d1);
$day_str = floor($time/3600/24);
$day_str = $day_str ? $day_str .= '天 ' : '';
$hour_str = floor($time%(24*3600)/3600);
$hour_str = $hour_str ? $hour_str .= '小時 ' : '';
$minute_str = floor($time%3600/60);
$minute_str = $minute_str ? $minute_str .= '分' : '';
/*
$second_str = $time%3600%60;
$second_str = $second_str ? $second_str .= ' seconds ' : '';
$n_time = floor($time/3600/24)."days".floor($time%(24*3600)/3600)."Hour".floor($time%3600/60)."Minute".($time%3600%60)."Second";
*/
$n_time = $day_str . $hour_str . $minute_str;
return $n_time;
}
// 在席車位檢查未有入場資料清單
public function pks_check_list($max_rows)
{
$data = array();
$data = $this->db
->select('pksno, lpr, in_time, pic_name')
->from('pks')
->where(array('status' => 'LR', 'cario_no' => 0, 'confirms' => 0, 'station_no' => STATION_NO))
->order_by('in_time', 'desc')
->limit($max_rows)
->get()
->result_array();
return $data;
}
// 重設在席查核
public function reset_pks_check()
{
// 讀出未查核過的資料
$data_pks = $this->db
->select('pksno, lpr, in_time')
->from('pks')
->where(array('status' => 'LR', 'cario_no' => 0, 'station_no' => STATION_NO))
->get()
->result_array();
// $tot = $this->db->num_rows(); // 總筆數
$tot = count($data_pks); // 總筆數
$num_cario = 0; // 入場資料筆數
foreach($data_pks as $rows)
{
$lpr = $rows['lpr'];
if ($lpr == 'NONE') continue; // 車辨失敗者不處理
$pksno = $rows['pksno'];
$pks_in_time = $rows['in_time'];
// 讀取進場時間, 如讀不到資料, 以目前時間取代(add by TZUSS 2016-02-23)
$rows_cario = $this->db
->select('cario_no, in_time')
->from('cario')
->where(array('in_out' => 'CI', 'obj_id' => $lpr, 'finished' => 0, 'err' => 0, 'station_no' => STATION_NO))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
// if ($this->db->num_rows() == 1) // 有入場資料
if (!empty($rows_cario['cario_no'])) // 有入cario_no場資料
{
$cario_no = $rows_cario['cario_no']; // 入場序號
$in_time = $rows_cario['in_time'];
// 在席與入場資料相符, 分別在cario與pks記錄之
$data = array
(
'pksno' => $pksno,
'pks_time' => $pks_in_time
);
$this->db->update('cario', $data, array('cario_no' => $cario_no, 'station_no' => STATION_NO));
$data = array
(
'cario_no' => $cario_no,
'in_time' => $in_time
);
// 車號及照片檔名填入資料庫內
$this->db->update('pks', $data, array('pksno' => $pksno, 'station_no' => STATION_NO));
++$num_cario;
}
}
return array('tot' => $tot, 'tot_correct' => $num_cario);
}
// 更正在席車號
public function correct_pks_lpr($pksno, $lpr)
{
// 讀取進場時間, 如讀不到資料, 以目前時間取代(add by TZUSS 2016-02-23)
$rows_cario = $this->db
->select('cario_no, in_time')
->from('cario')
->where(array('in_out' => 'CI', 'obj_id' => $lpr, 'finished' => 0, 'err' => 0, 'station_no' => STATION_NO))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
if (!empty($rows_cario['cario_no'])) // 有cario_no入場資料
{
$cario_no = $rows_cario['cario_no']; // 入場序號
$in_time = $rows_cario['in_time'];
// 在席與入場資料相符, 分別在cario與pks記錄之
$data = array
(
'pksno' => $pksno,
'pks_time' => $in_time
);
$this->db->update('cario', $data, array('cario_no' => $cario_no, 'station_no' => STATION_NO));
$data = array
(
'confirms' => 1,
'cario_no' => $cario_no,
'lpr' => $lpr,
'in_time' => $in_time
);
// 車號及照片檔名填入資料庫內
$this->db->update('pks', $data, array('pksno' => $pksno, 'station_no' => STATION_NO));
$results = array
(
'err' => 0,
'cario_no' => $cario_no
);
}
else // 無入場資料
{
$data = array
(
'confirms' => 1,
'lpr' => $lpr
);
$this->db->update('pks', $data, array('pksno' => $pksno, 'station_no' => STATION_NO));
$results = array
(
'err' => 0,
'cario_no' => 0 // 車號查無入場資料
);
}
return $results;
}
// 入場車號查核在席無資料清單
public function carin_check_list($max_rows)
{
$data = array();
$rows_cario = $this->db
->select('cario_no, obj_id as lpr, in_time, member_no, in_pic_name')
->from('cario')
->where('in_out', 'CI')
->where(array('pksno' => 0, 'finished' => 0, 'err' => 0, 'confirms' => 0, 'station_no' => STATION_NO, 'in_time <=' => 'date_sub(now(), interval 20 minute)'), null, false)
->order_by('cario_no', 'desc')
->limit($max_rows)
->get()
->result_array();
$idx = 0;
foreach($rows_cario as $rows)
{
$data[$idx++] = array
(
'cario_no' => $rows['cario_no'],
'lpr' => $rows['lpr'],
'in_time' => $rows['in_time'],
'type' => $rows['member_no'] == 0 ? '' : '月租',
'pic_name' => str_replace('-', '', substr($rows['in_time'], 0, 10)) . '/' . $rows['in_pic_name']
);
}
return $data;
}
// 更正入場車號
public function correct_carin_lpr($cario_no, $lpr, $in_time)
{
$rows = $this->db
->select('pksno, cario_no, in_time')
->from('pks')
->where(array('status' => 'LR', 'lpr' => $lpr, 'confirms' => 0, 'station_no' => STATION_NO))
->limit(1)
->get()
->row_array();
// 如果在席資料相符
if (!empty($rows['pksno']))
{
$pksno = $rows['pksno'];
$data = array
(
'cario_no' => $cario_no,
'in_time' => $in_time
);
$this->db->update('pks', $data, array('pksno' => $pksno, 'station_no' => STATION_NO));
$data_cario = array
(
'obj_id' => $lpr,
'pksno' => $pksno,
'pks_time' => $in_time,
'confirms' => 1
);
}
else // 無在席資料
{
$data_cario = array
(
'obj_id' => $lpr,
'pksno' => 0,
'confirms' => 1
);
}
$this->db->update('cario', $data_cario, array('cario_no' => $cario_no, 'station_no' => STATION_NO));
return(array('pksno' => $data_cario['pksno']));
}
// 查詢行動支付記錄
public function tx_bill_query()
{
$sql = "SELECT
tx_bill.order_no as order_no, tx_bill.lpr as lpr, tx_bill.invoice_no as invoice_no, tx_bill.in_time as in_time, tx_bill.balance_time as balance_time, tx_bill.company_no as company_no, tx_bill.email as email, tx_bill.mobile as mobile, tx_bill.amt as amt, tx_bill.tx_time as tx_time,
allpay_feedback_log.rtn_msg as rtn_msg, allpay_feedback_log.payment_type as payment_type,
cario.out_before_time as out_before_time
FROM tx_bill
LEFT JOIN cario ON tx_bill.cario_no = cario.cario_no
LEFT JOIN allpay_feedback_log ON tx_bill.order_no = allpay_feedback_log.merchant_trade_no
WHERE tx_bill.status = 111
ORDER BY tx_bill.tx_time DESC";
return $this->db->query($sql)->result_array();
}
// 查詢月租繳款機記錄
public function tx_bill_ats_query()
{
$sql = "SELECT
tx_bill_ats.order_no as order_no, tx_bill_ats.lpr as lpr, tx_bill_ats.invoice_no as invoice_no,
tx_bill_ats.end_time as end_time, tx_bill_ats.next_start_time as next_start_time, tx_bill_ats.next_end_time as next_end_time,
tx_bill_ats.company_no as company_no, tx_bill_ats.email as email, tx_bill_ats.mobile as mobile, tx_bill_ats.amt as amt,
tx_bill_ats.remarks as remarks, tx_bill_ats.member_name as member_name, tx_bill_ats.tx_time as tx_time,
allpay_feedback_log.rtn_msg as rtn_msg, allpay_feedback_log.payment_type as payment_type
FROM tx_bill_ats
LEFT JOIN allpay_feedback_log ON tx_bill_ats.order_no = allpay_feedback_log.merchant_trade_no
WHERE tx_bill_ats.status = 111
ORDER BY tx_bill_ats.tx_time DESC";
return $this->db->query($sql)->result_array();
}
// 查詢樓層在席群組
public function pks_group_query()
{
$sql = "SELECT
pks_groups.station_no, pks_groups.group_name as group_name, pks_groups.tot as tot, pks_groups.parked as parked, pks_groups.availables as availables, pks_groups.group_id as group_id, pks_groups.renum as renum
FROM pks_groups
ORDER BY pks_groups.group_id DESC";
return $this->db->query($sql)->result_array();
}
// 送出至message queue(目前用mqtt)
public function mq_send($topic, $msg)
{
$this->vars['mqtt']->publish($topic, $msg, 0);
trigger_error("mqtt:{$topic}|{$msg}");
}
}

+ 653
- 0
models/Carpayment_model.php 파일 보기

@@ -0,0 +1,653 @@
<?php
/*
file: carpayment_model.php
*/
require_once(ALTOB_SYNC_FILE) ;
class Carpayment_model extends CI_Model
{
var $vars = array();
var $io_name = array('I' => '車入', 'O' => '車出', 'MI' => '機入', 'MO' => '機出', 'FI' => '樓入', 'FO' => '樓出');
var $now_str;
function __construct()
{
parent::__construct();
$this->load->database();
$this->now_str = date('Y-m-d H:i:s');
}
public function init($vars)
{
$this->vars = $vars;
}
// 博辰通知付款完成
public function p2payed($parms, $opay=false)
{
$result = $this->db->select("in_time, cario_no, station_no")
->from('cario')
->where(array('obj_type' => 1, 'obj_id' => $parms['lpr'], 'finished' => 0, 'err' => 0))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
// 查不到車號才找備援碼
if(!isset($result['in_time']) && is_numeric($parms['lpr']) && strlen($parms['lpr']) == 6)
{
$result = $this->db->select("in_time, cario_no, station_no")
->from('cario')
->where(array('obj_type' => 1, 'ticket_no' => $parms['lpr'], 'finished' => 0, 'err' => 0))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
// 找不到記錄
if(!isset($result['in_time']))
{
trigger_error(__FUNCTION__ . '..not found..' . print_r($parms, true));
return false;
}
$in_time = new DateTime($result['in_time']);
$pay_time = new DateTime($parms['pay_time']);
// 若間隔小於 15 分鐘, 拿現在時間來當付款時間
$parms['pay_time'] = (($pay_time->getTimestamp() - $in_time->getTimestamp()) / 60 < 15) ? $this->now_str : $parms['pay_time'];
if($opay)
{
// A. (備援碼)歐付寶
$parms2 = array('seqno' => $result['cario_no'], 'amt' => $parms['amt'], 'lpr' => $parms['lpr']);
return $this->m2payed($parms2);
}
else
{
// B. (備援碼)一般繳費機
$data = array
(
'out_before_time' => date('Y-m-d H:i:s', strtotime("{$parms['pay_time']} + 15 minutes")),
'pay_time' => $parms['pay_time'],
'pay_type' => $parms['pay_type'],
'payed' => 1
);
$this->db->where(array('cario_no' => $result['cario_no']))->update('cario', $data);
if (!$this->db->affected_rows())
{
trigger_error("(備援碼) 付款失敗:{$parms['lpr']}|{$data['out_before_time']}");
return 'fail';
}
trigger_error("(備援碼) 付款後更新時間:{$parms['lpr']}|{$data['out_before_time']}");
return 'ok';
}
}
// A. 歐付寶
if($opay)
{
$parms2 = array('seqno' => $result['cario_no'], 'amt' => $parms['amt'], 'lpr' => $parms['lpr']);
$result = $this->m2payed($parms2);
if($result != 'ok')
return $result;
}
else
{
// B. 一般繳費機
$in_time = new DateTime($result['in_time']);
$pay_time = new DateTime($parms['pay_time']);
// 若間隔小於 15 分鐘, 拿現在時間來當付款時間
$parms['pay_time'] = (($pay_time->getTimestamp() - $in_time->getTimestamp()) / 60 < 15) ? $this->now_str : $parms['pay_time'];
$data = array
(
'out_before_time' => date('Y-m-d H:i:s', strtotime("{$parms['pay_time']} + 15 minutes")),
'pay_time' => $parms['pay_time'],
'pay_type' => $parms['pay_type'],
'payed' => 1
);
$this->db
->where(array('obj_type' => 1, 'obj_id' => $parms['lpr'], 'finished' => 0, 'err' => 0))
->update('cario', $data);
if (!$this->db->affected_rows())
{
trigger_error("付款失敗:{$parms['lpr']}|{$data['out_before_time']}");
return 'fail';
}
trigger_error("付款後更新時間:{$parms['lpr']}|{$data['out_before_time']}");
}
// 傳送付款更新記錄
$sync_agent = new AltobSyncAgent();
$sync_agent->init($result['station_no'], $result['in_time']);
$sync_agent->cario_no = $result['cario_no']; // 進出編號
$sync_result = $sync_agent->sync_st_pay($parms['lpr'], $parms['pay_time'], $parms['pay_type'],
date('Y-m-d H:i:s', strtotime("{$parms['pay_time']} + 15 minutes")));
trigger_error( "..sync_st_pay.." . $sync_result);
return 'ok';
}
// 繳費機告知已付款 (new 2016/07/15)
// http://localhost/carpayment.html/ats2payed/車牌/金額/場站編號/序號/MD5
// md5(車牌.金額.場站編號.序號)
public function ats2payed($parms)
{
$order_no = $parms['order_no'];
$bill_result = $this->db->from('tx_bill_ats')
->where(array('order_no' => $order_no, 'status' => 111))
->limit(1)
->get()
->row_array();
if(!empty($bill_result)){
$member_no = $bill_result['member_no'];
$station_no = $bill_result['station_no'];
$next_start_time = $bill_result['next_start_time'];
$next_end_time = $bill_result['next_end_time'];
$data = array(
'end_date' => $bill_result['next_end_time'] // TODO: 有被任何一筆序號蓋資料的可能
);
$this->db
->where(array('member_no' => $member_no, 'station_no' => $station_no))
->update('members', $data);
if ($this->db->affected_rows())
{
trigger_error("繳費機更新會員資料完成,{$parms['lpr']},金額:{$parms['amt']},序號:{$parms['order_no']}");
return 'ok';
}
else
{
trigger_error("繳費機更新會員資料失敗,{$parms['lpr']},金額:{$parms['amt']},序號:{$parms['order_no']}");
return 'fail';
}
}
}
// 行動支付, 手機告知已付款
// http://203.75.167.89/carpayment.html/m2payed/ABC1234/120/12112/12345/1f3870be274f6c49b3e31a0c6728957f
// http://203.75.167.89/carpayment.html/m2payed/車牌/金額/場站編號/序號/MD5
// md5(車牌.金額.場站編號.序號)
public function m2payed($parms)
{
$data = array
(
'out_before_time' => date('Y-m-d H:i:s', strtotime(" + 15 minutes")),
'pay_time' => date('Y-m-d H:i:s'),
'pay_type' => 4, // 歐付寶行動支付
'payed' => 1
);
$this->db
->where(array('cario_no' => $parms['seqno']))
->update('cario', $data);
if ($this->db->affected_rows())
{
trigger_error("歐付寶行動支付成功,{$parms['lpr']}金額:{$parms['amt']},序號:{$parms['seqno']}");
return 'ok';
}
else
{
trigger_error("歐付寶行動支付失敗,{$parms['lpr']}金額:{$parms['amt']},序號:{$parms['seqno']}");
return 'fail';
}
}
/*
月租繳款完成
http://203.75.167.89/carpayment.html/memberpayed/12345/ABC1234/120/12112/1/2016-01-31/1f3870be274f6c49b3e31a0c6728957f
http://203.75.167.89/carpayment.html/memberpayed/會員號碼/車牌/金額/場站編號/月繳/本期到期日/md5
md5(會員號碼.車牌.金額.場站編號.月繳.本期到期日)
public function memberpayed($parms)
{
// update members (???)
}
*/
// 模糊比對
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;
}
// 取得進場資訊 (模糊比對)
function q_fuzzy_pks($word)
{
if(empty($word) || strlen($word) < 4 || strlen($word) > 10)
{
return null;
}
// 備援數字使用
else if(is_numeric($word) && strlen($word) == 6)
{
trigger_error(__FUNCTION__ . '..備援查詢: ' . $word);
$sql = "SELECT obj_id as lpr, ticket_no
FROM cario
WHERE finished = 0 AND err = 0
AND out_before_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY)
AND ticket_no = {$word}
ORDER BY out_before_time DESC";
$retults = $this->db->query($sql)->result_array();
return $retults;
}
$fuzzy_statement = $this->getLevenshteinSQLStatement($word, 'obj_id');
//trigger_error("模糊比對 {$word} where: {$fuzzy_statement}");
$sql = "SELECT obj_id as lpr, ticket_no
FROM cario
WHERE {$fuzzy_statement} AND finished = 0 AND err = 0
AND out_before_time > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 5 DAY)
GROUP BY obj_id
ORDER BY out_before_time DESC";
$retults = $this->db->query($sql)->result_array();
return $retults;
}
// 建立博辰查詢入場時間資料 (by ticket_no)
function gen_query_data_type4($ticket_no)
{
$data = array();
// s2. 完整車牌號碼: 右邊補空格補滿7碼
$data['lpr'] = $ticket_no;
// s3. 塔號_車格號碼: 該車牌相關車輛所停車的停車塔號或樓層號碼,
// 地下室部分為負值例如B1為-1,平面停車場為1,二樓為2 (左邊補 ‘0’ 補滿2碼),
// 停車格號4碼(左邊補 ‘0’ 補滿4碼),
// 樓層和停車格號中間以 ‘_’ 分隔,例如:”01_0101”
$data['seat_no'] = 'XX_XXXX';
$data['ticket'] = 0;
$data['start_date'] = '2000/01/01';
$data['end_date'] = '2000/01/01';
$data['start_time'] = '00:00';
$data['end_time'] = '00:00';
$result = $this->db->select("in_time, date_format(pay_time, '%Y/%m/%d %T') as pay_time, in_pic_name, member_no")
->from('cario')
->where(array('obj_type' => 1, 'ticket_no' => $ticket_no, 'finished' => 0, 'err' => 0))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
if (!empty($result['in_time']))
{
// s5. 入場時間: 格式為"yyyy/MM/dd HH:mm:ss",時間為24小時制,若無紀錄秒數秒數部分可填”00”
$data['in_time'] = $result['in_time'];
// s6. 入場車牌圖片路徑: 貴公司的絕對路徑,我方使用網路芳鄰或FTP下載
$pic_name_arr = explode('-', $result['in_pic_name']);
$date_num = substr($pic_name_arr[7], 0, 8);
$data['in_pic_name'] = "\\\\192.168.10.201\\pics\\{$date_num}\\{$result['in_pic_name']}";
// s7. 繳費時間: 無繳費時間時為"2000/01/01 00:00:00",格式為"yyyy/MM/dd HH:mm:ss",時間為24小時制,若無紀錄秒數秒數部分可填”00”
$data['pay_time'] = !empty($result['pay_time']) ? $result['pay_time'] : '2000/01/01 00:00:00';
}
else
{
$data['in_time'] = '';
$data['in_pic_name'] = '';
$data['pay_time'] = '2000/01/01 00:00:00';
}
return $data;
}
// 建立博辰查詢入場時間資料
function gen_query_data($lpr)
{
$data = array();
// s2. 完整車牌號碼: 右邊補空格補滿7碼
$data['lpr'] = $lpr; //str_pad($lpr, 7, ' ', STR_PAD_RIGHT);
// s3. 塔號_車格號碼: 該車牌相關車輛所停車的停車塔號或樓層號碼,
// 地下室部分為負值例如B1為-1,平面停車場為1,二樓為2 (左邊補 ‘0’ 補滿2碼),
// 停車格號4碼(左邊補 ‘0’ 補滿4碼),
// 樓層和停車格號中間以 ‘_’ 分隔,例如:”01_0101”
$sql = "select p.pksno, m.group_id
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['pksno']))
{
$data['seat_no'] = ($rows['group_id'] == 'B1' ? '-1' : '0' . substr($rows['group_id'], -1)) . '_0' . substr($rows['pksno'], -3);
}
else
{
$data['seat_no'] = 'XX_XXXX'; // '-1_0028';
}
// 查詢是否月租會員
$result = $this->db->select("date_format(start_date, '%Y/%m/%d') as start_date, date_format(end_date,'%Y/%m/%d') as end_date")
->from('members')
->where(array(
'lpr' => $lpr,
'start_date <' => $this->vars['date_time'],
'end_date >=' => $this->vars['date_time'])
, false)
->limit(1)
->get()
->row_array();
if (!empty($result['start_date'])) // 月租會員
{
$data['ticket'] = 1; // s4. 是否為月票: 0:非月票, 1:月票
$data['start_date'] = $result['start_date'];// s8. 有效起始時間: 非月票時為"2000/01/01", 格式為"yyyy/MM/dd"
$data['end_date'] = $result['end_date']; // s9. 有效截止日期: 非月票時為"2000/01/01", 格式為"yyyy/MM/dd"
$data['start_time'] = '00:00'; // s10. 使用起始時段: 非月票時為"00:00", 格式為"HH:mm"
$data['end_time'] = '23:59'; // s11. 使用結束時段: 非月票時為"00:00", 格式為"HH:mm"
}
else // 臨停車
{
$data['ticket'] = 0;
$data['start_date'] = '2000/01/01';
$data['end_date'] = '2000/01/01';
$data['start_time'] = '00:00';
$data['end_time'] = '00:00';
}
$result = $this->db->select("in_time, date_format(pay_time, '%Y/%m/%d %T') as pay_time, in_pic_name, member_no")
->from('cario')
->where(array('obj_type' => 1, 'obj_id' => $lpr, 'finished' => 0, 'err' => 0))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
if (!empty($result['in_time']))
{
// s5. 入場時間: 格式為"yyyy/MM/dd HH:mm:ss",時間為24小時制,若無紀錄秒數秒數部分可填”00”
$data['in_time'] = $result['in_time'];
// s6. 入場車牌圖片路徑: 貴公司的絕對路徑,我方使用網路芳鄰或FTP下載
$pic_name_arr = explode('-', $result['in_pic_name']);
$date_num = substr($pic_name_arr[7], 0, 8);
$data['in_pic_name'] = "\\\\192.168.10.201\\pics\\{$date_num}\\{$result['in_pic_name']}";
// s7. 繳費時間: 無繳費時間時為"2000/01/01 00:00:00",格式為"yyyy/MM/dd HH:mm:ss",時間為24小時制,若無紀錄秒數秒數部分可填”00”
$data['pay_time'] = !empty($result['pay_time']) ? $result['pay_time'] : '2000/01/01 00:00:00';
}
else
{
$data['in_time'] = '';
$data['in_pic_name'] = '';
$data['pay_time'] = '2000/01/01 00:00:00';
}
return $data;
}
// 博辰查詢入場時間 (fuzzy)
public function query_in_fuzzy($lpr)
{
$fuzzy_result = $this->q_fuzzy_pks($lpr);
if(!empty($fuzzy_result) && count($fuzzy_result) > 0)
{
$data = array();
// s2 ~ s11 的資料會因模糊比對筆數增加或減少而增減
foreach ($fuzzy_result as $idx => $rows)
{
$lpr = $rows['lpr'];
$ticket_no = $rows['ticket_no'];
if($lpr == 'NONE')
{
$tmp_data = $this->gen_query_data_type4($ticket_no); // 備緩搜尋
}
else
{
$tmp_data = $this->gen_query_data($lpr); // 模糊搜尋
}
if($tmp_data['in_time'] == '')
{
// 若查無入場時間, 直接乎略這筆
trigger_error("查無入場時間, 直接乎略這筆[{$lpr}]:".print_r($rows, true));
}
else
{
$data['results'][$idx] = $tmp_data;
}
}
$data['count'] = count($fuzzy_result);
}
else
{
$data_0 = array();
$data_0['lpr'] = str_pad($lpr, 7, ' ', STR_PAD_RIGHT);
$data_0['seat_no'] = 'XX_XXXX';
$data_0['ticket'] = 0;
$data_0['start_date'] = '2000/01/01';
$data_0['end_date'] = '2000/01/01';
$data_0['start_time'] = '00:00';
$data_0['end_time'] = '00:00';
$data_0['in_time'] = '';
$data_0['pay_time'] = '2000/01/01 00:00:00';
$data_0['in_pic_name'] = '';
$data = array();
$data['results'][0] = $data_0;
$data['count'] = 0;
}
trigger_error("fuzzy aps查詢入場時間[{$lpr}]:".print_r($data, true));
return $data;
}
// 博辰查詢入場時間
public function query_in($lpr)
{
$data = array();
// 讀取樓層數, group_type = 2為樓層
$sql = "select p.pksno, m.group_id
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['pksno']))
{
$data['seat_no'] = ($rows['group_id'] == 'B1' ? '-1' : '0' . substr($rows['group_id'], -1)) . '_' . substr($rows['pksno'], -3);
}
else
{
$data['seat_no'] = 'XX_XXXX';
}
// 查詢是否月租會員
$result = $this->db->select("date_format(start_date, '%Y/%m/%d') as start_date, date_format(end_date,'%Y/%m/%d') as end_date")
->from('members')
->where(array('lpr' => $lpr, 'end_date >=' => $this->vars['date_time']), false)
->limit(1)
->get()
->row_array();
if (!empty($result['start_date'])) // 月租會員
{
$data['ticket'] = 1;
$data['start_date'] = $result['start_date'];
$data['end_date'] = $result['end_date'];
$data['start_time'] = '00:00';
$data['end_time'] = '23:59';
}
else // 臨停車
{
$data['ticket'] = 0;
$data['start_date'] = '2000/01/01';
$data['end_date'] = '2000/01/01';
$data['start_time'] = '00:00';
$data['end_time'] = '00:00';
}
$result = $this->db->select("in_time, date_format(pay_time, '%Y/%m/%d %T') as pay_time, in_pic_name, member_no")
->from('cario')
->where(array('obj_type' => 1, 'obj_id' => $lpr, 'finished' => 0, 'err' => 0))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
if (!empty($result['in_time']))
{
trigger_error("aps查詢入場時間|{$lpr}|{$result['in_time']}|{$result['in_pic_name']}");
$data['in_time'] = $result['in_time'];
$data['pay_time'] = !empty($result['pay_time']) ? $result['pay_time'] : '2000/01/01 00:00:00';
$pic_name_arr = explode('-', $result['in_pic_name']);
$date_num = substr($pic_name_arr[7], 0, 8);
//$data['in_pic_name'] = "\\\\192.168.10.201\\pics\\{$date_num}\\{$result['in_pic_name']}"; // 2016/07/25 update
//$data['in_pic_name'] = "D:/altob/home/data/parkings/cars/pics/{$date_num}/{$result['in_pic_name']}"; // 2016/07/25 update
$data['in_pic_name'] = "\\\\192.168.10.201\\pics\\{$date_num}\\{$result['in_pic_name']}"; // 2016/07/25 update
// $data['in_pic_name'] = "{$date_num}/{$result['in_pic_name']}";
$data['records'] = 1;
}
else
{
$data['in_time'] = '';
$data['pay_time'] = '2000/01/01 00:00:00';
$data['in_pic_name'] = '';
$data['records'] = 0;
}
trigger_error("aps查詢入場時間[{$lpr}]:".print_r($data, true));
// return array('in_time' => '', 'in_pic_name' => '', 'records' => 0, 'ticket' => 0, 'seat_no' => 'XX_XXXX');
return $data;
}
// 行動設備查詢入場時間
// http://203.75.167.89/carpayment.html/m2query_in/ABC1234/12112/1f3870be274f6c49b3e31a0c6728957f
// http://203.75.167.89/carpayment.html/m2query_in/車牌/場站編號/MD5
// 回傳0: 失敗, 成功: 12345,60(第一欄位非0數字代表成功, 第二欄位為金額), 此值在付款時必需傳回, 否則視為非法
public function m2query_in($parms)
{
$result = $this->db->select('cario_no, out_before_time')
->from('cario')
->where(array('obj_type' => 1, 'obj_id' => $parms['lpr'], 'station_no' => $parms['station_no'], 'finished' => 0, 'err' => 0))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
if (!empty($result['cario_no']))
{
trigger_error("行動設備查詢入場時間成功|{$lpr}|{$result['cario_no']}|{$result['in_time']}");
// call計費模組
$amt = 10;
}
else
{
$result['cario_no'] = 0;
$amt = 0;
trigger_error('行動設備查詢入場時間失敗'.print_r($parms, true));
}
return "{$result['cario_no']},{$amt}";
}
// 臨停未結清單
public function cario_temp_not_finished_query_all($station_no, $q_item, $q_str)
{
$where_station = $station_no == 0 ? '' : " station_no = {$station_no} and "; // 如為0, 則全部場站讀取
switch($q_item)
{
case 'in_time':
$items = "{$q_item} >=";
$q_str .= ' 23:59:59';
break;
case 'lpr':
$items = "{$q_item} like ";
$q_str = strtoupper($q_str).'%';
break;
default:
$items = "{$q_item} like ";
$q_str .= '%';
break;
}
$sql = "
SELECT
cario_no,
station_no,
obj_id as lpr,
in_time,
out_before_time,
pay_time
FROM cario
WHERE
{$where_station} {$items} '{$q_str}'
and obj_type = 1 and finished = 0 and err = 0 and confirms = 0
and member_no = 0
and out_time is null
ORDER BY cario.cario_no asc
";
//trigger_error(__FUNCTION__ . "test sql: {$sql}");
$results = $this->db->query($sql)->result_array();
return $results;
}
}

+ 1281
- 0
models/Cars_model.php
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 185
- 0
models/Ctbcbank_model.php 파일 보기

@@ -0,0 +1,185 @@
<?php
/*
file: Ctbcbank_model.php 付費系統 (CTBC 中國信託)
*/
class Ctbcbank_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
/*
// ----- 中國信託 - 測試環境 -----
define('CTBC_SSLAuthUI', "https://testepos.ctbcbank.com/auth/SSLAuthUI.jsp"); // URL授權介面
define('CTBC_TYPE1_merID', "10063"); // 特店編號 (交易類型:一般授權)
define('CTBC_TYPE1_MerchantID', "8220276806667"); // 銀行所授與的特店代號,純數字,固定 13 碼。
define('CTBC_TYPE1_TerminalID', "90008466"); // 銀行所授與的終端機代號,純數字,固定 8 碼。
define('CTBC_TYPE1_Key', "ZQFsGRIzb7NqsPcWOLKOL3sj"); // 壓碼 (可由後台重新產生)
define('CTBC_TYPE2_merID', "10064"); // 特店編號 (交易類型:分期付款)
define('CTBC_TYPE2_MerchantID', "8220878791047");
define('CTBC_TYPE2_TerminalID', "91001008");
define('CTBC_TYPE3_merID', "10065"); // 特店編號 (交易類型:紅利折抵)
define('CTBC_TYPE3_MerchantID', "8220800211437");
define('CTBC_TYPE3_TerminalID', "92000235");
// ----- 中國信託 - 測試環境 (END) -----
*/
// ----- 中國信託 - 正式環境 -----
define('CTBC_SSLAuthUI', "https://epos.chinatrust.com.tw/auth/SSLAuthUI.jsp"); // URL授權介面
define('CTBC_TYPE1_merID', "10012"); // 特店編號 (交易類型:一般授權)
define('CTBC_TYPE1_MerchantID', "8220131400023"); // 銀行所授與的特店代號,純數字,固定 13 碼。
define('CTBC_TYPE1_TerminalID', "99810789"); // 銀行所授與的終端機代號,純數字,固定 8 碼。
define('CTBC_TYPE1_Key', "4qH0cNXhsmk6jKdTT4hjwYCX"); // 壓碼 (可由後台重新產生)
// ----- 中國信託 - 正式環境 (END) -----
}
// 3.中國信託
public function transfer_money_ctbc($data, $return_url)
{
try{
$lidm = $data['order_no']; // 訂單編號 (<=19 碼)
$purchAmt = $data['amt'];
$txType = "0"; // 交易方式,長度為一碼數字。(一般交易:0, 分期交易:1, 紅利折抵一般交易:2, 紅利折抵分期交易:4)
$debug = "0"; // 預設(進行交易時)請填0,偵錯時請填1。
// 使用 CTBCAgent
include_once(ALTOB_CTBC_FILE);
$oCTBCAgent = new CTBCAgent();
$oCTBCAgent->MerchantID = CTBC_TYPE1_MerchantID;
$oCTBCAgent->TerminalID = CTBC_TYPE1_TerminalID;
$oCTBCAgent->AuthResURL = $return_url;// 從收單行端取得授權碼後,要導回的網址,請勿填入特殊字元@、#、%、?、&等。
$oCTBCAgent->SSLAuthUI = CTBC_SSLAuthUI; // URL授權介面
$oCTBCAgent->Option = "1"; // 一般交易請填「1」。 , 分期交易請填一到兩碼的分期期數。, 紅利交易請填固定兩碼的產品代碼。, 紅利分期交易請填第一至二碼固定為產品代碼,第三碼或三至四碼為分期期數。
$oCTBCAgent->Key = CTBC_TYPE1_Key;
$oCTBCAgent->MerchantName = iconv("UTF-8", "big5", "歐特儀停車場");
$oCTBCAgent->OrderDetail = iconv("UTF-8", "big5", "歐Pa卡");
$oCTBCAgent->AutoCap = "1"; // (0–不自動請款, 1–自動請款)
$oCTBCAgent->Customize = "1"; // 設定刷卡頁顯示特定語系或客制化頁面。(1–繁體中文, 2–簡體中文, 3–英文, 5–客制化頁面)
$data = array(
'merID' => CTBC_TYPE1_merID,
'lidm' => $lidm,
'purchAmt' => $purchAmt,
'txType' => $txType,
'debug' => $debug,
'target' => "_self"
);
$oCTBCAgent->CheckOut($data);
}catch (Exception $e){
// 例外錯誤處理。
throw $e;
}
}
// 3.中國信託 - 回傳
public function ctbcbank_return_handler($resenc, $merid)
{
try{
// 使用 CTBCAgent
include_once(ALTOB_CTBC_FILE);
$oCTBCAgent = new CTBCAgent();
$oCTBCAgent->Key = CTBC_TYPE1_Key;
$debug = "0";
// 解密
$data = array(
'encRes' => $resenc,
'debug' => $debug
);
$EncArray = $oCTBCAgent->Decrypt($data);
/*
foreach($EncArray AS $name => $val){
echo $name ."=>". urlencode(trim($val,"\x00..\x08")) ."\n";
}
*/
$errdesc = isset($EncArray['errdesc']) ? $EncArray['errdesc'] : "";
$authresurl = isset($EncArray['authresurl']) ? $EncArray['authresurl'] : "";
$xid = isset($EncArray['xid']) ? $EncArray['xid'] : "";
$awardedpoint = isset($EncArray['awardedpoint']) ? $EncArray['awardedpoint'] : "";
$status = isset($EncArray['status']) ? $EncArray['status'] : "";
$errcode = isset($EncArray['errcode']) ? $EncArray['errcode'] : "";
$authcode = isset($EncArray['authcode']) ? $EncArray['authcode'] : "";
$authamt = isset($EncArray['authamt']) ? $EncArray['authamt'] : "";
$lidm = isset($EncArray['lidm']) ? $EncArray['lidm'] : "";
$offsetamt = isset($EncArray['offsetamt']) ? $EncArray['offsetamt'] : "";
$originalamt = isset($EncArray['originalamt']) ? $EncArray['originalamt'] : "";
$utilizedpoint = isset($EncArray['utilizedpoint']) ? $EncArray['utilizedpoint'] : "";
$numberofpay = isset($EncArray['numberofpay']) ? $EncArray['numberofpay'] : ""; // option: 一般交易, 分期交易
$prodcode = isset($EncArray['prodcode']) ? $EncArray['prodcode'] : ""; // option: 紅利交易
$last4digitpan = isset($EncArray['last4digitpan']) ? $EncArray['last4digitpan'] : "";
$pidresult= isset($EncArray['pidresult']) ? $EncArray['pidresult'] : "";
$cardnumber = isset($EncArray['cardnumber']) ? $EncArray['cardnumber'] : "";
$outmac = isset($EncArray['outmac']) ? $EncArray['outmac'] : "";
$data = array(
'status' => $status,
'errcode' => $errcode,
'authcode' => $authcode,
'authamt' => $authamt,
'lidm' => $lidm,
'offsetamt' => $offsetamt,
'originalamt' => $originalamt,
'utilizedpoint' => $utilizedpoint,
'numberofpay' => $numberofpay,
'prodcode' => $prodcode,
'last4digitpan' => $last4digitpan,
'debug' => $debug
);
// 取得 check mac
$MACString = $oCTBCAgent->CheckMac($data);
//echo "checkm=$MACString\n";
//echo "outmac=$outmac\n";
// 驗証內容正確性
if(strcmp($MACString, $outmac) == 0){
$data = array(
'errdesc' => $errdesc,
'authresurl' => $authresurl,
'xid' => $xid,
'awardedpoint' => $awardedpoint,
'prodcode' => $prodcode,
'merid' => $merid,
'status' => $status,
'errcode' => $errcode,
'authcode' => $authcode,
'authamt' => $authamt,
'lidm' => $lidm,
'offsetamt' => $offsetamt,
'originalamt' => $originalamt,
'utilizedpoint' => $utilizedpoint,
'numberofpay' => $numberofpay,
'last4digitpan' => $last4digitpan,
'pidresult' => $pidresult,
'cardnumber' => $cardnumber,
'outmac' => $outmac
);
}else{
// CHECK MAC FAIL
$data = array(
'errdesc' => "[CHECK MAC FAIL] MACString=$MACString",
'merid' => $merid,
'outmac' => $outmac
);
}
$this->db->insert('ctbc_feedback_log', $data); // 記錄 log
return $data;
}catch (Exception $e){
// 例外錯誤處理。
trigger_error(__FUNCTION__.$e->getMessage());
}
}
}

+ 265
- 0
models/Excel_model.php 파일 보기

@@ -0,0 +1,265 @@
<?php
/*
file: Excel_model.php 匯出報表專用
*/
class Excel_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
$this->now_str = date('Y-m-d H:i:s');
ini_set('max_execution_time','300');
ini_set('memory_limit','512M');
}
public function init($vars)
{
$this->vars = $vars;
}
// 會員名單報表
public function export_members()
{
trigger_error(EXPORT_LOG_TITLE. '..start..' . __FUNCTION__);
// 讀入廠站資料
$sql = "
select
members.member_name as member_name,
members.lpr as lpr,
members.contract_no as contract_no,
members.start_date as start_date,
members.end_date as end_date,
members.amt as amt,
members.update_time as update_time,
members.member_attr,
members.fee_period,
members.mobile_no,
members.deposit,
members.suspended,
members.locked,
members.valid_time
from members
ORDER BY update_time DESC
";
$results = $this->db->query($sql)->result_array();
if(empty($results))
{
trigger_error(EXPORT_LOG_TITLE.'..no data..' . $this->db->last_query());
return false;
}
//$total_count = $this->db->query($sql)->num_rows();
// 產生 Excel
$this->load->library('excel');
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$col_A_mapping = array('col_name' => 'A', 'col_title' => '會員名稱', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_B_mapping = array('col_name' => 'B', 'col_title' => '車牌號碼', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_C_mapping = array('col_name' => 'C', 'col_title' => '合約代碼', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_D_mapping = array('col_name' => 'D', 'col_title' => '開始時間', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_E_mapping = array('col_name' => 'E', 'col_title' => '結束時間', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_F_mapping = array('col_name' => 'F', 'col_title' => '租金', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_G_mapping = array('col_name' => 'G', 'col_title' => '最後更新時間', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_H_mapping = array('col_name' => 'H', 'col_title' => '身份', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_I_mapping = array('col_name' => 'I', 'col_title' => '繳期', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_J_mapping = array('col_name' => 'J', 'col_title' => '電話', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_K_mapping = array('col_name' => 'K', 'col_title' => '押金', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_L_mapping = array('col_name' => 'L', 'col_title' => '停權 (營管操作)', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_M_mapping = array('col_name' => 'M', 'col_title' => '鎖車 (會員操作)', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_N_mapping = array('col_name' => 'N', 'col_title' => '有效期限 (審核後更新)', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$raw_index = 1;
$objPHPExcel->getActiveSheet()->setTitle('下載');
$objPHPExcel->getActiveSheet()->setCellValue($col_A_mapping['col_name'].$raw_index, $col_A_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_B_mapping['col_name'].$raw_index, $col_B_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_C_mapping['col_name'].$raw_index, $col_C_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_D_mapping['col_name'].$raw_index, $col_D_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_E_mapping['col_name'].$raw_index, $col_E_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_F_mapping['col_name'].$raw_index, $col_F_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_G_mapping['col_name'].$raw_index, $col_G_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_H_mapping['col_name'].$raw_index, $col_H_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_I_mapping['col_name'].$raw_index, $col_I_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_J_mapping['col_name'].$raw_index, $col_J_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_K_mapping['col_name'].$raw_index, $col_K_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_L_mapping['col_name'].$raw_index, $col_L_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_M_mapping['col_name'].$raw_index, $col_M_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_N_mapping['col_name'].$raw_index, $col_N_mapping['col_title']);
$warning_style = array(
//'alignment' => array('horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER),
'font' => array(
'bold' => true,
'color' => array('rgb' => 'FF0000'),
'size' => 16,
'name' => 'Verdana'
)
);
$hq_info = $this->vars['mcache']->get('info');
$count = 0;
foreach($results as $rows)
{
$raw_index += 1;
$member_name = $rows['member_name'];
$lpr = $rows['lpr'];
$contract_no = $rows['contract_no'] ? $rows['contract_no'] : '';
$start_date = $rows['start_date'];
$end_date = $rows['end_date'];
$amt = $rows['amt'] ? $rows['amt'] : '0';
$update_time = $rows['update_time'];
$member_attr = ( empty($hq_info['member_attr']) || empty($rows['member_attr']) || empty($hq_info['member_attr'][$rows['member_attr']]) ) ? '無' : $hq_info['member_attr'][$rows['member_attr']];
$fee_period = ( empty($hq_info['period_name']) || empty($rows['fee_period']) || empty($hq_info['period_name'][$rows['fee_period']]) ) ? '無' : $hq_info['period_name'][$rows['fee_period']];
$mobile_no = $rows['mobile_no'];
$deposit = $rows['deposit'];
$suspended = (empty($rows['suspended'])) ? '無' : '已停權';
$locked = (empty($rows['locked'])) ? '無' : '已鎖車';
$valid_time = $rows['valid_time'];
$count++;
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_A_mapping['col_name'].$raw_index, $member_name, $col_A_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_B_mapping['col_name'].$raw_index, $lpr, $col_B_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_C_mapping['col_name'].$raw_index, $contract_no, $col_C_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_D_mapping['col_name'].$raw_index, $start_date, $col_D_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_E_mapping['col_name'].$raw_index, $end_date, $col_E_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_F_mapping['col_name'].$raw_index, $amt, $col_F_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_G_mapping['col_name'].$raw_index, $update_time, $col_G_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_H_mapping['col_name'].$raw_index, $member_attr, $col_H_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_I_mapping['col_name'].$raw_index, $fee_period, $col_I_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_J_mapping['col_name'].$raw_index, $mobile_no, $col_J_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_K_mapping['col_name'].$raw_index, $deposit, $col_K_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_L_mapping['col_name'].$raw_index, $suspended, $col_L_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_M_mapping['col_name'].$raw_index, $locked, $col_M_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_N_mapping['col_name'].$raw_index, $valid_time, $col_N_mapping['col_type']);
// 設定 style
if($valid_time != $end_date)
{
$objPHPExcel->getActiveSheet()->getStyle($col_N_mapping['col_name'].$raw_index)->applyFromArray($warning_style);
}
}
// 網站下載
$filename_prefix = iconv('UTF-8', 'Big5', '會員資料 - '. STATION_NAME);
$filename_postfix = iconv('UTF-8', 'Big5', '(現況)');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $filename_prefix. ' - ' . $filename_postfix . '.xlsx');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
trigger_error(EXPORT_LOG_TITLE . '..completed..' . __FUNCTION__ . '|count:' . $count);
return true;
}
// 進出記錄報表
public function export_cario_data($query_year, $query_month)
{
ini_set('max_execution_time','300');
ini_set('memory_limit','512M');
trigger_error(EXPORT_LOG_TITLE. '..start..' . __FUNCTION__ . "|{$query_year},{$query_month}");
// 讀入廠站資料
$sql = "
SELECT
cario.obj_id AS plate_no,
cario.in_time as in_time,
cario.out_time as out_time,
members.member_name as member_name,
CONCAT( FLOOR(HOUR(TIMEDIFF(cario.in_time, cario.out_time)) / 24), ' 日 ',
MOD(HOUR(TIMEDIFF(cario.in_time, cario.out_time)), 24), ' 時 ',
MINUTE(TIMEDIFF(cario.in_time, cario.out_time)), ' 分') as time_period
FROM cario
left join members on cario.member_no = members.member_no
WHERE cario.err = 0 and cario.obj_id != 'NONE'
and YEAR(cario.in_time) = {$query_year} and MONTH(cario.in_time) = {$query_month}
and cario.out_time is not null
ORDER BY cario.in_time ASC
";
$results = $this->db->query($sql)->result_array();
if(empty($results))
{
trigger_error(EXPORT_LOG_TITLE.'..no data..' . $this->db->last_query());
return false;
}
//$total_count = $this->db->query($sql)->num_rows();
// 產生 Excel
$this->load->library('excel');
$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);
$col_A_mapping = array('col_name' => 'A', 'col_title' => '車牌號碼', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_B_mapping = array('col_name' => 'B', 'col_title' => '進場時間', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_C_mapping = array('col_name' => 'C', 'col_title' => '離場日期', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_D_mapping = array('col_name' => 'D', 'col_title' => '停車時數', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_E_mapping = array('col_name' => 'E', 'col_title' => '場站名稱', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$col_F_mapping = array('col_name' => 'F', 'col_title' => '會員名稱', 'col_type' => PHPExcel_Cell_DataType::TYPE_STRING);
$raw_index = 1;
$objPHPExcel->getActiveSheet()->setTitle('下載');
$objPHPExcel->getActiveSheet()->setCellValue($col_A_mapping['col_name'].$raw_index, $col_A_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_B_mapping['col_name'].$raw_index, $col_B_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_C_mapping['col_name'].$raw_index, $col_C_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_D_mapping['col_name'].$raw_index, $col_D_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_E_mapping['col_name'].$raw_index, $col_E_mapping['col_title']);
$objPHPExcel->getActiveSheet()->setCellValue($col_F_mapping['col_name'].$raw_index, $col_F_mapping['col_title']);
$count = 0;
foreach($results as $rows)
{
$raw_index += 1;
$plate_no = $rows['plate_no'];
$in_time = $rows['in_time'];
$out_time = $rows['out_time'];
$time_period = $rows['time_period'];
$member_name = $rows['member_name'] ? $rows['member_name'] : '臨停';
$count++;
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_A_mapping['col_name'].$raw_index, $plate_no, $col_A_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_B_mapping['col_name'].$raw_index, $in_time, $col_B_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_C_mapping['col_name'].$raw_index, $out_time, $col_C_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_D_mapping['col_name'].$raw_index, $time_period, $col_D_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_E_mapping['col_name'].$raw_index, STATION_NAME, $col_E_mapping['col_type']);
$objPHPExcel->getActiveSheet()->setCellValueExplicit($col_F_mapping['col_name'].$raw_index, $member_name, $col_F_mapping['col_type']);
}
// 儲存檔案
/*
$filename_prefix = iconv('UTF-8', 'Big5', '車牌號碼進出記錄 - '. STATION_NAME);
$filename_postfix = iconv('UTF-8', 'Big5', $query_year . '年' .$query_month.'月份');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save(EXPORT_BASE.$filename_prefix.' - '.$filename_postfix.'.xlsx');
*/
// 網站下載
$filename_prefix = iconv('UTF-8', 'Big5', '車牌號碼進出記錄 - '. STATION_NAME);
$filename_postfix = iconv('UTF-8', 'Big5', $query_year . '年' .$query_month.'月份');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $filename_prefix. ' - ' . $filename_postfix . '.xlsx');
header('Cache-Control: max-age=0');
$objWriter->save('php://output');
trigger_error(EXPORT_LOG_TITLE . '..completed..' . __FUNCTION__ . '|count:' . $count);
return true;
}
}

+ 60
- 0
models/Landb_model.php 파일 보기

@@ -0,0 +1,60 @@
<?php
/*
file: Landb_model.php 撈區網資料庫
*/
class Landb_model extends CI_Model
{
function __construct()
{
parent::__construct();
// 資料庫連線
//$dsn_old_db = 'mysqli://root:HISHARP@192.168.0.2:3306/parking';
//$this->dsn_old_db = $this->load->database($dsn_old_db, true);
$this->now_str = date('Y-m-d H:i:s');
}
// test
public function test($lpr)
{
$result = $lpr.' @ '. $this->now_str.' @ ';
$sql = "SELECT ParkingNum as pksno, LPR as lpr
FROM table_carpark where lpr = 'xxx'";
$dsn_old_db = $this->load->database('old_db', true);
/*
$config['hostname'] = '192.168.0.2';
$config['port'] = "3306";
$config['username'] = 'root';
$config['password'] = 'HISHARP';
$config['database'] = 'parking';
$config['dbdriver'] = 'mysqli';
$config['dbprefix'] = '';
$config['pconnect'] = FALSE;
$config['db_debug'] = TRUE;
$config['cache_on'] = FALSE;
$config['cachedir'] = '';
$config['char_set'] = 'utf8';
$config['dbcollat'] = 'utf8_general_ci';
$dsn_old_db = $this->load->database($config, true);
*/
$retults = $dsn_old_db->query($sql)->result_array();
//$retults = $this->dsn_old_db->query($sql)->result_array();
$seat_no = '';
if(!empty($retults[0]))
{
$seat_no = '-'.substr($retults[0]['pksno'], 0, 1).'_'.substr($retults[0]['pksno'], 1);
}
return
'result >>>>>' . $result . '@' . '<br/>'.
$sql . '<br/>'.
json_encode($retults, true).'<br/>'.
$seat_no;
}
}

+ 194
- 0
models/Parkingquery_model.php 파일 보기

@@ -0,0 +1,194 @@
<?php
/*
file: Parkingquery_model.php 停車管理系統(提供資策會使用)
*/
class Parkingquery_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
}
public function init($vars)
{
// do nothing
}
// 查詢各樓層剩餘車位
// http://203.75.167.89/parkingquery.html/check_space/12345
public function check_space($seqno)
{
$data = array();
$results = $this->db->select('group_id, availables, tot')
->from('pks_groups')
->where('group_type', 1)
->get()
->result_array();
foreach($results as $idx => $rows)
{
$data['result']['floor'][$idx] = array
(
'floor_name' => $rows['group_id'],
'valid_count' => $rows['availables'],
'total_count' => $rows['tot']
);
}
return $data;
}
// 停車位置查詢(板橋好停車)
// http://203.75.167.89/parkingquery.html/check_location/ABC1234
public function check_location($lpr)
{
$lpr = strtoupper($lpr); // 一律轉大寫
$data = array();
$rows = $this->db->select('pksno, pic_name')
->from('pks')
->where('lpr', $lpr)
->limit(1)
->get()
->row_array();
if (!empty($rows['pksno']))
{
$data['result']['num'] = $lpr;
$data['result']['location_no'] = "{$rows['pksno']}";
$data['result_code'] = 'OK';
$data['result']['pic_name'] = $rows['pic_name'];
}
else // 查無資料, 啟用模糊比對
{
// 讀取最近一筆入場資料
$rows_cario = $this->db
->select('cario_no')
->from('cario')
->where(array('in_out' => 'CI', 'obj_id' => $lpr, 'finished' => 0, 'err' => 0, 'out_time IS NULL' => null))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
// 有入場記錄, 直接猜在頂樓
if (!empty($rows_cario['cario_no']))
{
$data['result']['num'] = $lpr;
$data['result']['location_no'] = "7000";
$data['result_code'] = 'OK';
}
else
{
$data['result']['num'] = $lpr;
$data['result']['location_no'] = '0';
$data['result_code'] = 'FAIL';
}
}
return $data;
}
// 空車位導引
// http://203.75.167.89/parkingquery.html/get_valid_seat
// 註記現在時間, 並保留10分鐘
public function get_valid_seat($pksno)
{
$data = array();
$this->db->trans_start();
if ($pksno > 0) // 限制從某一個車位開始指派車位
{
$sql = "select pksno from pks where status = 'VA' and pksno >= {$pksno} and prioritys != 0 and (book_time is null or book_time <= now()) order by prioritys asc limit 1 for update;";
}
else
{
$sql = "select pksno from pks where status = 'VA' and prioritys != 0 and (book_time is null or book_time <= now()) order by prioritys asc limit 1 for update;";
}
$rows = $this->db->query($sql)->row_array();
if (!empty($rows['pksno']))
{
$data['result']['location_no'] = "{$rows['pksno']}";
$data['result_code'] = 'OK';
$sql = "update pks set book_time = addtime(now(), '00:10:00') where pksno = {$rows['pksno']};";
$this->db->query($sql);
}
else
{
$data['result']['location_no'] = '0';
$data['result_code'] = 'FAIL';
}
$this->db->trans_complete();
return $data;
}
// 緊急求救
// http://203.75.167.89/parkingquery.html/send_sos/B2/111/123
public function send_sos($floor, $x, $y)
{
$data = array
(
'result' => array('send_from' => array('floor' => $floor, 'x' => $x, 'y' => $y)),
'result_code' => 'OK'
);
return $data;
}
// 防盜鎖車
// http://203.75.167.89/parkingquery.html/security_action/ABC1234/pswd/2
public function security_action($lpr, $pswd, $action)
{
$data = array();
/*
$rows = $this->db->select('member_no, passwd, locked')
->from('members')
->where(array('lpr' => $lpr, 'passwd' => $pswd))
->limit(1)
->get()
->row_array();
trigger_error('防盜鎖車:'.$this->db->last_query());
// 無資料或密碼錯誤
if (empty($rows['member_no']))
{
$data['result_code'] = 'FAIL';
return($data);
}
*/
$rows = $this->db->select('member_no, passwd, locked')
->from('members')
->where(array('lpr' => $lpr))
->limit(1)
->get()
->row_array();
trigger_error('防盜鎖車:'.$this->db->last_query());
// 無資料或密碼錯誤
if (empty($rows['member_no']) || md5($rows['passwd']) != $pswd)
{
$data['result_code'] = 'FAIL';
return($data);
}
$data['result_code'] = 'OK';
// 查詢防盜狀態
if ($action == 2)
{
$data['result']['action'] = 'CHECK_SECURITY';
$data['result'][0]['num'] = $lpr;
$data['result'][0]['result'] = $rows['locked'] ? 'ON' : 'OFF';
return $data;
}
$this->db
->where('member_no', $rows['member_no'])
->update('members', array('locked' => $action));
$data['result']['action'] = $action == 1 ? 'ON' : 'OFF';
return $data;
}
}

+ 167
- 0
models/Payment_ats_model.php 파일 보기

@@ -0,0 +1,167 @@
<?php
/*
file: Payment_ats_model.php 繳費機
*/
class Payment_ats_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
define('PAYMENT_ATS_INVOICE_REMARK', '繳費機帳單');
define('TABLE_NAME_TX_BILL_ATS', 'tx_bill_ats');
}
// 狀態: 結帳完成
public function transfer_money_done($order_no)
{
$data = array();
$data['status'] = 1; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
$this->db->update(TABLE_NAME_TX_BILL_ATS, $data, array('order_no' => $order_no));
return true;
}
// 狀態: 錢沒對上
public function transfer_money_done_with_amt_error($order_no)
{
$data = array();
$data['status'] = 2; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
$this->db->update(TABLE_NAME_TX_BILL_ATS, $data, array('order_no' => $order_no));
return true;
}
// 狀態: 發票沒建立
public function transfer_money_set_invoice_error($order_no)
{
$data = array();
$data['status'] = 3; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
$this->db->update(TABLE_NAME_TX_BILL_ATS, $data, array('order_no' => $order_no));
return true;
}
// 狀態: 訂單逾期作廢
public function transfer_money_timeout($order_no)
{
$data = array();
$data['status'] = 99; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
$this->db->update(TABLE_NAME_TX_BILL_ATS, $data, array('order_no' => $order_no));
return true;
}
// 狀態: 交易失敗
public function transfer_money_done_with_tx_error($order_no)
{
$data = array();
$data['status'] = 101; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
$this->db->update(TABLE_NAME_TX_BILL_ATS, $data, array('order_no' => $order_no));
return true;
}
// 狀態: 產品已領取
public function transfer_money_done_and_finished($order_no)
{
$data = array();
$data['status'] = 111; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
$this->db->update(TABLE_NAME_TX_BILL_ATS, $data, array('order_no' => $order_no));
return true;
}
// 建立帳單 (會員)
public function create_member_bill($lpr)
{
$result = $this->db->select("station_no, member_no, member_name, date_format(end_date, '%Y-%m-%d') as end_date, amt, remarks,
date_add(date_format(end_date, '%Y-%m-%d'), INTERVAL 1 day) as next_start,
date_add(date_format(end_date, '%Y-%m-%d'), INTERVAL 1 MONTH) as next_end", false)
->from('members')
->where('lpr', $lpr)
->get()
->row_array();
if(empty($result['member_no'])){
// 查無會員資料
$data = array();
$data['member_no'] = 0;
return $data;
}
else
{
// 建立會員帳單
$data = array();
$data['invoice_remark'] = PAYMENT_ATS_INVOICE_REMARK;
$data['order_no'] = $result['member_no'].time(); // 交易序號
$data['station_no'] = $result['station_no']; // 場站編號
$data['member_no'] = $result['member_no']; // 會員編號
$data['member_name'] = $result['member_name']; // 車主姓名
//$data['amt'] = 10; // 租金金額 (test only)
$data['amt'] = $result['amt']; // 租金金額
$data['remarks'] = $result['remarks']; // 備註
$data['end_time'] = $result['end_date'] . ' 23:59:59'; // 到期日
$data['next_start_time'] = $result['next_start']. ' 00:00:00'; // 次期起始日
$data['next_end_time'] = $result['next_end'] . ' 23:59:59'; // 次期到期日
$data['lpr'] = strtoupper($lpr); // 車牌號碼
$data['balance_time_limit'] = date("Y-m-d H:i:s", strtotime('+ 15 minutes')); // 帳單有效期限 15 min
$this->db->insert(TABLE_NAME_TX_BILL_ATS, $data);
return $data;
}
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no."|{$lpr}|無資料");
}
// 繳交帳單 (帳單)
public function pay_bill($order_no, $invoice_receiver, $company_no, $email, $mobile, $clientBackUrl, $orderResultUrl, $serviceUrl, $tx_type=0)
{
$data = $this->get_tx_bill($order_no);
if (!empty($data))
{
if($data['status'] != 0){
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no."|error status: ". $data['status']);
return null;
}
if(strlen($invoice_receiver) >= 7){ // 手機載具編號
$data['invoice_receiver'] = '/'.$invoice_receiver;
}
if(strlen($company_no) >= 8){ // 公司統編
$data['company_no'] = $company_no;
$data['company_receiver'] = "公司名稱";
$data['company_address'] = "公司地址";
}
if(strlen($email) >= 5){ // a@b.c
$data['email'] = $email;
}
if(strlen($mobile) >= 10){ // 手機
$data['mobile'] = $mobile;
}
$txTime = time(); // 產生交易時間
if(strtotime($data['balance_time_limit']) - $txTime > 0){
$data['status'] = 100; //狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
$data['tx_time'] = date('Y/m/d H:i:s', $txTime);
$data['tx_type'] = $tx_type; // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址
$data['client_back_url'] = $clientBackUrl;
$data['order_result_url'] = $orderResultUrl;
$data['service_url'] = $serviceUrl;
$this->db->update(TABLE_NAME_TX_BILL_ATS, $data, array('order_no' => $order_no));
return $data;
}
$this->transfer_money_timeout($order_no); // 訂單逾期作廢
return null;
}
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no."|無帳單資料");
}
// 取得帳單資料
public function get_tx_bill($order_no)
{
$result = $this->db
->from(TABLE_NAME_TX_BILL_ATS)
->where(array('order_no' => $order_no))
->limit(1)
->get()
->row_array();
return $result;
}
}

+ 185
- 0
models/Payment_model.php 파일 보기

@@ -0,0 +1,185 @@
<?php
/*
file: Payment_model.php 付費系統 (臨停)
*/
class Payment_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
define("PAYMENT_INVOICE_REMARK", "臨停繳交帳單");
}
// 狀態: 結帳完成
public function transfer_money_done($order_no)
{
$data = array();
$data['status'] = TX_BILL_STATUS_PAID;
$this->db->update('tx_bill', $data, array('order_no' => $order_no));
return true;
}
// 狀態: 錢沒對上
public function transfer_money_done_with_amt_error($order_no)
{
$data = array();
$data['status'] = TX_BILL_STATUS_ERROR_AMT;
$this->db->update('tx_bill', $data, array('order_no' => $order_no));
return true;
}
// 狀態: 發票沒建立
public function transfer_money_set_invoice_error($order_no)
{
$data = array();
$data['status'] = TX_BILL_STATUS_ERROR_INVOICE;
$this->db->update('tx_bill', $data, array('order_no' => $order_no));
return true;
}
// 狀態: 訂單逾期作廢
public function transfer_money_timeout($order_no)
{
$data = array();
$data['status'] = TX_BILL_STATUS_TIME_OUT;
$this->db->update('tx_bill', $data, array('order_no' => $order_no));
return true;
}
// 狀態: 交易失敗
public function transfer_money_done_with_tx_error($order_no)
{
$data = array();
$data['status'] = TX_BILL_STATUS_FAIL;
$this->db->update('tx_bill', $data, array('order_no' => $order_no));
return true;
}
// 狀態: 產品已領取
public function transfer_money_done_and_finished($order_no)
{
$data = array();
$data['status'] = TX_BILL_STATUS_DONE;
$this->db->update('tx_bill', $data, array('order_no' => $order_no));
return true;
}
// 建立帳單 (臨停)
public function create_cario_bill($lpr)
{
$result = $this->db->select('station_no, cario_no, in_time, pay_time, out_time, out_before_time, member_no')
->from('cario')
->where(array('obj_type' => 1, 'obj_id' => $lpr, 'finished' => 0, 'err' => 0))
->order_by('cario_no', 'desc')
->limit(1)
->get()
->row_array();
if(!empty($result['member_no'])){
// 會員不算臨停帳單
$data = array();
$data['member_no'] = $result['member_no'];
return $data;
}
else if (!empty($result['out_before_time']))
{
$inTime = $result['out_before_time']; // 進場時間認這個欄位
$balanceTime = date('Y-m-d H:i:s');
$stationNo = $result['station_no'];
require_once(ALTOB_BILL_FILE); // 臨停費率
$oPayment = new AltobPayment();
$oPayment->ServiceURL = ALTOB_PAYMENT_TXDATA_URL;
$bill = $oPayment->getBill($inTime, $balanceTime, $stationNo);
// create tx_bill
$data = array();
$data['invoice_remark'] = PAYMENT_INVOICE_REMARK;
$data['order_no'] = $result['cario_no'].time(); // 交易序號
$data['cario_no'] = $result['cario_no']; // 進出場序號 (金流結束後開門使用)
//$data['amt'] = ($bill[BillResultKey::price] > 0) ? 10 : 0; // 測試用
$data['amt'] = $bill[BillResultKey::price];
$data['balance_time_limit'] = date("Y-m-d H:i:s", strtotime('+ 15 minutes')); // 15 min
$data['balance_time'] = $balanceTime;
$data['in_time'] = $inTime;
$data['lpr'] = strtoupper($lpr);
$data['station_no'] = $stationNo;
if($bill[BillResultKey::price] > 0){
// 有費用才建立到tx_bill
$this->db->insert('tx_bill', $data);
}else{
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no."|{$lpr}|尚未產生款項");
}
// return data
$data['bill_days'] = $bill[BillResultKey::days];
$data['bill_hours'] = $bill[BillResultKey::hours];
$data['bill_mins'] = $bill[BillResultKey::mins];
$data['price_detail'] = $bill[BillResultKey::price_detail];
return $data;
}
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no."|{$lpr}|無車牌帳單資料");
}
// 繳交帳單 (帳單)
public function pay_bill($order_no, $invoice_receiver, $company_no, $email, $mobile, $clientBackUrl, $orderResultUrl, $serviceUrl, $tx_type=0)
{
$data = $this->get_tx_bill($order_no);
if (!empty($data))
{
if($data['status'] != 0){
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no."|error status: ". $data['status']);
return null;
}
if(strlen($invoice_receiver) >= 7){ // 手機載具編號
$data['invoice_receiver'] = '/'.$invoice_receiver;
}
if(strlen($company_no) >= 8){ // 公司統編
$data['company_no'] = $company_no;
$data['company_receiver'] = "公司名稱";
$data['company_address'] = "公司地址";
}
if(strlen($email) >= 5){ // a@b.c
$data['email'] = $email;
}
if(strlen($mobile) >= 10){ // 手機
$data['mobile'] = $mobile;
}
$txTime = time(); // 產生交易時間
if(strtotime($data['balance_time_limit']) - $txTime > 0){
$data['status'] = TX_BILL_STATUS_PROCESSING;
$data['tx_time'] = date('Y/m/d H:i:s', $txTime);
$data['tx_type'] = $tx_type; // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址
$data['client_back_url'] = $clientBackUrl;
$data['order_result_url'] = $orderResultUrl;
$data['service_url'] = $serviceUrl;
$this->db->update('tx_bill', $data, array('order_no' => $order_no));
return $data;
}
$this->transfer_money_timeout($order_no); // 訂單逾期作廢
return null;
}
trigger_error(APP_NAME.', '.__FUNCTION__.', order_no=>' . $order_no."|無帳單資料");
}
// 取得臨停帳單資料
public function get_tx_bill($order_no)
{
$result = $this->db
->from('tx_bill')
->where(array('order_no' => $order_no))
->limit(1)
->get()
->row_array();
return $result;
}
}

+ 356
- 0
models/Pks_model.php 파일 보기

@@ -0,0 +1,356 @@
<?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;
}
}

+ 349
- 0
models/Qcar_model.php 파일 보기

@@ -0,0 +1,349 @@
<?php
/*
file: Qcar_model.php 停車管理系統
*/
class Qcar_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']);
$rows['pic_name'] = $rows['pic_name'];
}
else // 查無資料, 啟用模糊比對
{
$len = strlen($lpr);
if ($len >= 5) // 檢查車牌號碼長度
{
$arr = explode(';', file_get_contents("http://192.168.11.253:8090/cgi-bin/parking_status.cgi?CMD=QUERY_SEAT&LPR={$lpr}"));
$pksno = $arr[0];
}
else
{
$pksno = 0; // 車牌號碼長度錯誤
}
trigger_error("電腦查詢模糊比對:[{$lpr}]:" . print_r($arr, true));
if ($pksno != 0) // 模糊比對成功
{
$sql = "select 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.pksno = {$pksno}
limit 1";
$rows_pks = $this->db->query($sql)->row_array();
$rows['pksno'] = $pksno;
// $rows['pic_name'] = str_replace('.jpg', '', $rows_pks['pic_name']);
$rows['pic_name'] = $rows_pks['pic_name'];
$rows['update_time'] = $rows_pks['update_time'];
$rows['in_time'] = $rows_pks['in_time'];
$rows['floors'] = $rows_pks['floors'];
$rows['posx'] = $rows_pks['posx'];
$rows['posy'] = $rows_pks['posy'];
$rows['group_id'] = $rows_pks['group_id'];
$rows['group_name'] = $rows_pks['group_name'];
}
else // 模糊比對仍是失敗
{
$rows['pksno'] = '0'; // 無該筆資料
}
}
*/
return $rows;
}
// 月租會員加入
public function q_rents($lpr)
{
$rows = $this->db->select("station_no, member_no, member_name, date_format(end_date, '%Y-%m-%d') as end_date, amt , date_add(date_format(end_date, '%Y-%m-%d'), INTERVAL 1 day) as next_start, date_add(date_format(end_date, '%Y-%m-%d'), INTERVAL 1 MONTH) as next_end", false)
->from('members')
->where('lpr', $lpr)
->get()
->row_array();
if (empty($rows['member_no'])) $rows['member_no'] = 0; // 無此資料
return $rows;
}
// 新增月租轉帳資料
public function transfer_money_create($data)
{
$this->db->insert('tx_money', $data);
}
// 更新月租轉帳資料 (已結帳)
public function transfer_money_done($order_no)
{
$data = array();
$data['status'] = 1; //狀態,0:剛建立, 1:已結帳, 2:錢沒對上
$this->db->update('tx_money', $data, array('order_no' => $order_no));
return true;
}
// 更新發票號碼
public function transfer_money_set_invoice($order_no, $invoice_no)
{
$data = array();
$data['invoice_no'] = $invoice_no;
$this->db->update('tx_money', $data, array('order_no' => $order_no));
return true;
}
// 找不到POS機
public function transfer_money_done_with_error_10($order_no)
{
$data = array();
$data['status'] = 10; //狀態,0:剛建立, 1:已結帳, 2:錢沒對上, 3:發票沒拿到, 4:手動調整, 10:找不到POS機
$this->db->update('tx_money', $data, array('order_no' => $order_no));
return true;
}
// 更新發票號碼失敗
public function transfer_money_set_invoice_error_4($order_no)
{
$data = array();
$data['status'] = 3; //狀態,0:剛建立, 1:已結帳, 2:錢沒對上, 3:發票沒拿到
$this->db->update('tx_money', $data, array('order_no' => $order_no));
return true;
}
// 更新月租轉帳資料 (錢沒對上)
public function transfer_money_done_with_error_2($order_no)
{
$data = array();
$data['status'] = 2; //狀態,0:剛建立, 1:已結帳, 2:錢沒對上
$this->db->update('tx_money', $data, array('order_no' => $order_no));
return true;
}
// 取得月租轉帳資料
public function get_tx_money($order_no)
{
$result = $this->db
->from('tx_money')
->where(array('order_no' => $order_no))
->get()
->result_array();
return $result;
}
// 歐付寶記錄
public function create_allpay_feedback_log($data)
{
$this->db->insert('allpay_feedback_log', $data);
return true;
}
// 將發票號碼加入資料庫
public function update_invoice_no($order_no, $invoice_no)
{
$this->db->where(array('order_no' => $order_no))
->update('tx_money', array('invoice_no' => $invoice_no));
}
// 新增發票記錄
public function invoice_log_create($data)
{
$this->db->insert('tx_invoice_log', $data);
}
// 新增發票記錄回傳
public function invoice_log_set_response($response_code, $invoice_no, $seqno)
{
$data = array();
$data['response_code'] = $response_code;
$this->db->update('tx_invoice_log', $data, array('invoice_no' => $invoice_no, 'seqno' => $seqno));
return true;
}
// 取得POS機資訊
public function get_tx_pos($pos_id)
{
$result = $this->db
->from('tx_pos')
->where(array('pos_id' => $pos_id))
->get()
->result_array();
return $result;
}
// 取得POS機資訊 by lan_ip
public function get_tx_pos_by_lan_ip($lan_ip)
{
$result = $this->db
->from('tx_pos')
->where(array('lan_ip' => $lan_ip))
->get()
->result_array();
return $result;
}
// 模糊比對
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;
/*
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']
);
}
*/
}
}

+ 84
- 0
models/Security_model.php 파일 보기

@@ -0,0 +1,84 @@
<?php
/*
file: Security_model.php 停車管理系統 (鎖車)
*/
class Security_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
}
// 更改會員密碼
public function change_pswd($lpr, $new_pswd)
{
$data = array('passwd' => $new_pswd);
$this->db->update('members', $data, array('lpr' => $lpr));
return 'ok';
}
// 防盜鎖車
// http://203.75.167.89/parkingquery.html/security_action/ABC1234/pswd/2
public function security_action($lpr, $pswd, $action)
{
$data = array();
/*
$rows = $this->db->select('member_no, passwd, locked')
->from('members')
->where(array('lpr' => $lpr, 'passwd' => $pswd))
->limit(1)
->get()
->row_array();
trigger_error('防盜鎖車:'.$this->db->last_query());
// 無資料或密碼錯誤
if (empty($rows['member_no']))
{
$data['result_code'] = 'FAIL';
return($data);
}
*/
$rows = $this->db->select('member_no, passwd, locked, lpr')
->from('members')
->where(array('lpr' => $lpr))
->limit(1)
->get()
->row_array();
trigger_error('防盜鎖車:'.$this->db->last_query());
// 無資料或密碼錯誤
if (empty($rows['member_no']) || md5($rows['passwd']) != $pswd)
{
// 密碼未設定且輸入密碼為車牌號碼
if(empty($rows['passwd']) && md5($rows['lpr']) == $pswd){
// do nothing
}else{
$data['result_code'] = 'FAIL';
return($data);
}
}
$data['result_code'] = 'OK';
// 查詢防盜狀態
if ($action == 2)
{
$data['result']['action'] = 'CHECK_SECURITY';
$data['result'][0]['num'] = $lpr;
$data['result'][0]['result'] = $rows['locked'] ? 'ON' : 'OFF';
return $data;
}
$this->db
->where('member_no', $rows['member_no'])
->update('members', array('locked' => $action));
$data['result']['action'] = $action == 1 ? 'ON' : 'OFF';
return $data;
}
}

+ 715
- 0
models/Sync_data_model.php 파일 보기

@@ -0,0 +1,715 @@
<?php
/*
file: Sync_data_model.php 資料同步相關
*/
define('SYNC_DATA_LOG_TITLE', 'sync://'); // LOG (sync)
define('SYNC_PKS_GROUP_ID_CI', 'C888'); // 汽車 888
define('SYNC_PKS_GROUP_ID_MI', 'M888'); // 機車 888
define('SYNC_API_URL', 'http://61.219.172.11:60123/admins_station.html/');
define('SYNC_DELIMITER_ST_NAME', ' & '); // (拆分) 場站名稱
define('SYNC_DELIMITER_ST_NO', ','); // (拆分) 場站編號
define('SYNC_DELIMITER_ST_INFO', '|'); // (拆分) 其它
define('MCACHE_STATION_NO_STR', 'station_no_str');
define('MCACHE_STATION_NAME_STR', 'station_name_str');
define('MCACHE_STATION_IP_STR', 'station_ip_str');
define('MCACHE_STATION_888_STR', 'station_888_str');
define('MCACHE_SYNC_888_TMP_LOG', 'sync_888_tmp_log'); // 暫存 888 進出
class Sync_data_model extends CI_Model
{
var $vars = array();
function __construct()
{
parent::__construct();
$this->load->database();
}
public function init($vars)
{
$this->vars = $vars;
}
// 送出至message queue(目前用mqtt)
public function mq_send($topic, $msg)
{
$this->vars['mqtt']->publish($topic, $msg, 0);
trigger_error("mqtt:{$topic}|{$msg}");
}
// ------------------------------------------------
//
// 在席系統同步 (START)
//
// ------------------------------------------------
// 同步 888
public function sync_888($parms)
{
$result = -888;
if(!isset($parms['lpr']) || !isset($parms['etag']) || !isset($parms['io']) ||
($parms['lpr'] == 'NONE' && $parms['etag'] == 'NONE')
)
{
trigger_error(__FUNCTION__ . '..NONE..'. print_r($parms, true));
return $result;
}
trigger_error(__FUNCTION__ . "..{$parms['sno']}|{$parms['io']}|{$parms['lpr']}|{$parms['etag']}..");
// [START] 擋相同車號進出
$skip_or_not = false;
$new_cars_tmp = array
(
'timestamp' => time(),
'sno_io' => $parms['sno'] . $parms['io'],
'lpr' => $parms['lpr'],
'etag' => $parms['etag']
);
$cars_tmp_log_arr = $this->vars['mcache']->get(MCACHE_SYNC_888_TMP_LOG);
if(empty($cars_tmp_log_arr))
{
$cars_tmp_log_arr = array();
}
if(isset($cars_tmp_log_arr[$new_cars_tmp['sno_io']]))
{
$last_cars_tmp = $cars_tmp_log_arr[$new_cars_tmp['sno_io']];
// 判斷是否跳過 (記錄於一小時內, 相同場站進出 lpr 或 etag)
if( ( ($last_cars_tmp['lpr'] == $new_cars_tmp['lpr'] && $last_cars_tmp['lpr'] != 'NONE') ||
($last_cars_tmp['etag'] == $new_cars_tmp['etag'] && $last_cars_tmp['etag'] != 'NONE') ) && $last_cars_tmp['timestamp'] > $new_cars_tmp['timestamp'] - 3600
)
$skip_or_not = true;
}
// 更新
$cars_tmp_log_arr[$new_cars_tmp['sno_io']] = $new_cars_tmp;
$this->vars['mcache']->set(MCACHE_SYNC_888_TMP_LOG, $cars_tmp_log_arr);
trigger_error(__FUNCTION__ . '..upd ' . MCACHE_SYNC_888_TMP_LOG . " |s:{$skip_or_not}|" . print_r($cars_tmp_log_arr, true));
// 跳過
if($skip_or_not)
{
trigger_error(__FUNCTION__ . '..skip..');
return false;
}
// [END] 擋相同車號進出
switch($parms['io'])
{
// 入場
case 'CI':
$result = $this->pks_availables_update(SYNC_PKS_GROUP_ID_CI, -1, false, $parms['sno']);
break;
case 'MI':
$result = $this->pks_availables_update(SYNC_PKS_GROUP_ID_MI, -1, false, $parms['sno']);
break;
// 出場
case 'CO':
$result = $this->pks_availables_update(SYNC_PKS_GROUP_ID_CI, 1, false, $parms['sno']);
break;
case 'MO':
$result = $this->pks_availables_update(SYNC_PKS_GROUP_ID_MI, 1, false, $parms['sno']);
break;
}
return $result;
}
// 微調剩餘車位數
public function pks_availables_update($group_id, $value, $is_renum=true, $station_no=STATION_NO)
{
$where_group_arr = array('group_id' => $group_id, 'station_no' => $station_no);
$rows = $this->db->select('renum, parked, tot')
->from('pks_groups')
->where($where_group_arr)
->limit(1)
->get()
->row_array();
$renum = $rows['renum'];
$parked = $rows['parked'];
$tot = $rows['tot'];
trigger_error("更新車位數|{$group_id}|{$value}|{$is_renum}|".print_r($rows, true));
if($is_renum)
{
// 一般微調
if($value == 0)
{
$this->db->where($where_group_arr)
->update('pks_groups', array('renum' => 0, 'parked' => 0, 'availables' => $tot));
trigger_error(__FUNCTION__ . '..reset everything and exit..');
return true; // 中斷
}
else if($value >= 1)
{
// 增加
$renum = $renum + 1;
}
else
{
// 減少
$renum = $renum - 1;
}
$availables = $tot - $parked + $renum;
// 防止負值
if($availables <= 0)
{
$availables = 0;
$parked = $tot;
$renum = 0;
trigger_error(__FUNCTION__ . '..ava < 0..auto set (ava = 0, parked = tot, renum = 0)..');
}
else if($availables >= $tot)
{
$availables = $tot;
$parked = 0;
$renum = 0;
trigger_error(__FUNCTION__ . '..ava > tot..auto set (ava = tot, parked = 0, renum = 0)..');
}
// 更新 db
$this->db->where($where_group_arr)
->update('pks_groups', array('parked' => $parked, 'availables' => $availables, 'renum' => $renum));
}
else
{
// 進出場
if($value == 0)
{
trigger_error(__FUNCTION__ . '..??? exit..');
return true; // 中斷
}
else if($value >= 1)
{
// 已停車位數減少, 空車位數增加
$parked = $parked - 1;
}
else
{
// 已停車位數增加, 空車位數減少
$parked = $parked + 1;
}
/*
// 防止負值
if($parked < 0)
{
$parked = 0;
$renum = 0; // 自動重設 renum
trigger_error(__FUNCTION__ . '..parked < 0..set (parked = 0, renum = 0)..');
}
else if($parked >= $tot)
{
$parked = $tot;
$renum = 0; // 自動重設 renum
trigger_error(__FUNCTION__ . '..parked > tot.. = tot..set (parked = tot, renum = 0)..');
}
*/
$availables = $tot - $parked + $renum;
// 防止負值
if($availables <= 0)
{
$availables = 0;
$parked = $tot;
$renum = 0;
trigger_error(__FUNCTION__ . '..ava < 0..auto set (ava = 0, parked = tot, renum = 0)..');
}
else if($availables >= $tot)
{
$availables = $tot;
$parked = 0;
$renum = 0;
trigger_error(__FUNCTION__ . '..ava > tot..auto set (ava = tot, parked = 0, renum = 0)..');
}
// 更新 db
$this->db->where($where_group_arr)
->update('pks_groups', array('parked' => $parked, 'availables' => $availables, 'renum' => $renum));
}
// 送出即時訊號
if($group_id == SYNC_PKS_GROUP_ID_CI)
{
$this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_888 . ",1,{$availables}" . MQ_ALTOB_888_END_TAG); // 送出 888 (汽車)
}
else if($group_id == SYNC_PKS_GROUP_ID_MI)
{
$this->mq_send(MQ_TOPIC_ALTOB, MQ_ALTOB_888 . ",2,{$availables}" . MQ_ALTOB_888_END_TAG); // 送出 888 (機車)
}
else
{
$availables_pad = str_pad($availables, 3, '0', STR_PAD_LEFT); // 補零
$this->mq_send(MQ_TOPIC_SUBLEVEL, "{$group_id},{$availables_pad}"); // 送出剩餘車位數給字幕機
}
return $this->db->affected_rows();
}
// ------------------------------------------------
//
// 在席系統同步 (END)
//
// ------------------------------------------------
// ------------------------------------------------
//
// 中控接收端 (START)
//
// ------------------------------------------------
// 同步場站會員 (功能: 會員同步)
public function sync_members($info_arr=array('station_no_arr' => STATION_NO))
{
$data_member_arr = array();
$data_car_arr = array();
try{
// 查現況
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, SYNC_API_URL . 'member_query_all_in_one');
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); //timeout in seconds
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($info_arr));
$data = curl_exec($ch);
curl_close($ch);
}catch (Exception $e){
trigger_error('error msg:'.$e->getMessage());
trigger_error(SYNC_DATA_LOG_TITLE . $e->getMessage());
}
$data_member_arr = json_decode($data, true);
if (sizeof($data_member_arr) <= 0)
{
trigger_error(SYNC_DATA_LOG_TITLE . '.. empty ..'); // 忽略完全沒會員的情況
return 'empty';
}
else
{
foreach($data_member_arr as $data)
{
// create member_car
$data_car = array
(
'station_no' => $data['station_no'],
'member_no' => $data['member_no'],
'lpr' => $data['lpr'],
'lpr_correct' => $data['lpr'],
'etag' => $data['etag'],
'start_time' => $data['start_date'],
'end_time' => $data['end_date']
);
array_push($data_car_arr, $data_car);
}
}
//trigger_error(SYNC_DATA_LOG_TITLE . '.. test ..' . print_r($data_member_arr, true));
$this->db->trans_start();
// 清空
$this->db->empty_table('members');
$this->db->empty_table('member_car');
// 建立 members
$this->db->insert_batch('members', $data_member_arr);
// 建立 member_car
$this->db->insert_batch('member_car', $data_car_arr);
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(SYNC_DATA_LOG_TITLE . '.. sync fail ..'. '| last_query: ' . $this->db->last_query());
return 'fail';
}
trigger_error(SYNC_DATA_LOG_TITLE . '.. sync completed ..');
return 'ok';
}
// 同步車牌更換 (功能: 換車牌同步)
public function sync_switch_lpr($switch_lpr_arr)
{
trigger_error( __FUNCTION__ . '..' . print_r($switch_lpr_arr, true));
$this->db->trans_start();
foreach($switch_lpr_arr as $data)
{
$station_no = $data['station_no'];
$member_no = $data['member_no'];
$old_lpr = $data['old_lpr'];
$new_lpr = $data['new_lpr'];
$new_data = array('lpr' => $new_lpr, 'lpr_correct' => $new_lpr, 'member_no' => $member_no);
$this->db->update('etag_lpr', $new_data, array('lpr_correct' => $old_lpr));
$affect_rows = $this->db->affected_rows();
trigger_error(SYNC_DATA_LOG_TITLE . "換車牌更新 etag_lpr 共[{$affect_rows}]筆..".print_r($data, true));
/*
if($station_no == STATION_NO)
{
$new_data = array('lpr' => $new_lpr, 'lpr_correct' => $new_lpr, 'member_no' => $member_no);
$this->db->update('etag_lpr', $new_data, array('lpr_correct' => $old_lpr));
$affect_rows = $this->db->affected_rows();
trigger_error(SYNC_DATA_LOG_TITLE . "換車牌更新 etag_lpr 共[{$affect_rows}]筆..".print_r($data, true));
}
else
{
trigger_error(SYNC_DATA_LOG_TITLE . __FUNCTION__ . "..資料異常..".print_r($data, true));
}
*/
}
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(SYNC_DATA_LOG_TITLE . '.. sync fail ..'. '| last_query: ' . $this->db->last_query());
return 'fail';
}
trigger_error(SYNC_DATA_LOG_TITLE . '.. sync completed ..');
return 'ok';
}
// 同步場站費率
public function sync_price_plan($info_arr=array('station_no_arr' => STATION_NO))
{
try{
// 查另一台主機
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, SYNC_API_URL . 'price_plan_query_all_in_one');
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5); //timeout in seconds
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($info_arr));
$data = curl_exec($ch);
curl_close($ch);
}catch (Exception $e){
trigger_error('error msg:'.$e->getMessage());
}
$decode_result = json_decode($data, true);
if (sizeof($decode_result) <= 0) return "empty";
$this->db->trans_start();
foreach ($decode_result as $key => $value)
{
$station_no = $value["station_no"];
$tx_price_plan_id = $value["txid"];
$tx_type = $value["tx_type"];
$price_plan_data = array
(
'station_no' => $station_no,
'tx_type' => $tx_type,
'remarks' => $value['remarks'],
'price_plan' => $value['price_plan'],
'start_time' => $value['start_time'],
'valid_time' => $value['valid_time']
);
// 刪除
$this->db->delete('tx_price_plan', array('station_no' => $station_no, 'tx_type' => $tx_type));
// 新增
$this->db->insert('tx_price_plan', $price_plan_data);
}
$this->db->trans_complete();
return "ok";
}
// 取得最新未結清 (功能: 行動支付)
public function get_last_unbalanced_cario($lpr)
{
$sql = "SELECT station_no, cario_no, in_time, pay_time, out_time, out_before_time, member_no
FROM cario
WHERE
obj_id = '{$lpr}' AND finished = 0 AND err = 0
ORDER BY cario_no DESC
LIMIT 1
";
$results = $this->db->query($sql)->result_array();
if(isset($results[0]))
return $results[0];
return false;
}
// 同步車位現況 (功能: 888 同步, 在席同步)
public function sync_pks_groups_reload($station_setting)
{
$info = array();
$station_no_arr = explode(SYNC_DELIMITER_ST_NO, $station_setting['station_no']);
$station_name_arr = explode(SYNC_DELIMITER_ST_NAME, $station_setting['station_name']);
$station_888_arr = explode(SYNC_DELIMITER_ST_INFO, $station_setting['station_888']);
foreach($station_no_arr as $key => $station_no)
{
if($station_888_arr[$key] == 1) // 啟用
array_push($info, array('station_no' => $station_no_arr[$key], 'station_name' => $station_name_arr[$key]));
else if($station_888_arr[$key] == 4) // 關閉
{
// 清除 888
$this->db->delete('pks_groups', array('station_no' => $station_no_arr[$key]));
}
else
{
trigger_error(__FUNCTION__ . '..unknown station_888:' . $station_888_arr[$key]);
}
}
if(empty($info))
return 'none';
return $this->sync_pks_groups($info, true);
}
// 同步車位現況 (功能: 888 同步, 在席同步)
public function sync_pks_groups($info_arr=array(array('station_no' => STATION_NO, 'station_name' => STATION_NAME)), $reload=false)
{
if($reload)
{
// 確認應該要有的 pks_groups
$pks_groups_arr = array();
$pks_groups_name_arr = array();
foreach($info_arr as $data)
{
$pks_key = $data['station_no'] . SYNC_DELIMITER_ST_INFO . SYNC_PKS_GROUP_ID_CI;
array_push($pks_groups_arr, $pks_key); // 汽車 888
$pks_key = $data['station_no'] . SYNC_DELIMITER_ST_INFO . SYNC_PKS_GROUP_ID_MI;
array_push($pks_groups_arr, $pks_key); // 機車 888
$pks_groups_name_arr[$data['station_no']] = $data['station_name']. '(888)'; // 群組名稱
}
// 過濾已存在的部份
$sql = "SELECT station_no, group_id FROM pks_groups";
$current_pks_group = $this->db->query($sql)->result_array();
foreach($current_pks_group as $data)
{
$pks_key = $data['station_no'] . SYNC_DELIMITER_ST_INFO . $data['group_id'];
$key = array_search($pks_key, $pks_groups_arr);
if($key !== false)
unset($pks_groups_arr[$key]);
}
// 建立缺少的部份
if(!empty($pks_groups_arr))
{
// [A.開始]
$this->db->trans_start();
foreach($pks_groups_arr as $new_data)
{
$pks_info = explode(SYNC_DELIMITER_ST_INFO, $new_data);
$new_pks_groups_data = array(
'station_no' => $pks_info[0],
'group_id' => $pks_info[1],
'tot' => 100, // 預設車位數
'availables' => 100, // 預設車位數
'floors' => 'TOT',
'group_name' => $pks_groups_name_arr[$pks_info[0]]
);
$this->db->insert('pks_groups', $new_pks_groups_data);
trigger_error(__FUNCTION__ . '..insert pks_groups..'. print_r($new_pks_groups_data, true));
}
// [C.完成]
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
trigger_error(__FUNCTION__ . '..trans_error..' . '| last_query: ' . $this->db->last_query());
return 'fail'; // 中斷
}
}
}
$sql = "SELECT pks_groups.station_no,
pks_groups.group_name as group_name, pks_groups.tot as tot, pks_groups.parked as parked, pks_groups.availables as availables, pks_groups.group_id as group_id, pks_groups.renum as renum
FROM pks_groups
ORDER BY pks_groups.group_id DESC";
$pks_group_query_data = $this->db->query($sql)->result_array();
//trigger_error(__FUNCTION__ . '..sync..' . print_r($pks_group_query_data, true));
// 同步
require_once(ALTOB_SYNC_FILE);
$sync_agent = new AltobSyncAgent();
$sync_agent->init(STATION_NO); // 已帶上的資料場站編號為主
$sync_result = $sync_agent->upd_pks_groups(json_encode($pks_group_query_data, JSON_UNESCAPED_UNICODE));
trigger_error( SYNC_DATA_LOG_TITLE . '..'. __FUNCTION__ . "..upd_pks_groups.." . $sync_result);
}
// 重新載入場站設定
public function reload_station_setting()
{
try{
// 查現況
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, SYNC_API_URL . 'station_setting_query');
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); //timeout in seconds
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array()));
$return_result = curl_exec($ch);
curl_close($ch);
}catch (Exception $e){
trigger_error('error msg:'.$e->getMessage());
}
$station_setting_result = json_decode($return_result, true);
if(!isset($station_setting_result['results']) || sizeof($station_setting_result['results']) <= 0)
{
trigger_error(__FUNCTION__ . '..fail..' . print_r($return_result, true));
return 'fail';
}
$station_ip_str = $station_setting_result['station_ip']; // 場站目前對外IP
$station_setting_arr = $station_setting_result['results'];
$station_no_arr = array();
$station_name_arr = array();
$station_888_arr = array();
foreach($station_setting_arr as $data)
{
array_push($station_no_arr, $data['station_no']);
array_push($station_name_arr, $data['short_name']);
array_push($station_888_arr, $data['station_888']);
}
$station_no_str = implode(SYNC_DELIMITER_ST_NO, $station_no_arr); // 取值時會用到
$station_name_str = implode(SYNC_DELIMITER_ST_NAME, $station_name_arr); // 純顯示
$station_888_str = implode(SYNC_DELIMITER_ST_INFO, $station_888_arr); // 場站888設定
// 設定到 mcache
$this->vars['mcache']->set(MCACHE_STATION_NO_STR, $station_no_str);
$this->vars['mcache']->set(MCACHE_STATION_NAME_STR, $station_name_str);
$this->vars['mcache']->set(MCACHE_STATION_IP_STR, $station_ip_str);
$this->vars['mcache']->set(MCACHE_STATION_888_STR, $station_888_str);
return 'ok';
}
// 取得目前場站設定
public function station_setting_query($reload=false)
{
$station_no_str = $this->vars['mcache']->get(MCACHE_STATION_NO_STR);
$station_name_str = $this->vars['mcache']->get(MCACHE_STATION_NAME_STR);
$station_ip_str = $this->vars['mcache']->get(MCACHE_STATION_IP_STR);
$station_888_str = $this->vars['mcache']->get(MCACHE_STATION_888_STR);
if($reload || empty($station_no_str) || empty($station_name_str) || empty($station_ip_str) || empty($station_888_str))
{
$result = $this->reload_station_setting();
if($result == 'ok')
{
$station_no_str = $this->vars['mcache']->get(MCACHE_STATION_NO_STR);
$station_name_str = $this->vars['mcache']->get(MCACHE_STATION_NAME_STR);
$station_ip_str = $this->vars['mcache']->get(MCACHE_STATION_IP_STR);
$station_888_str = $this->vars['mcache']->get(MCACHE_STATION_888_STR);
}
else
{
/*
$station_setting = array();
$station_setting['station_no'] = STATION_NO;
$station_setting['station_name'] = STATION_NAME;
$station_setting['station_ip'] = STATION_IP;
return $station_setting;
*/
return false;
}
}
$station_setting = array();
$station_setting['station_no'] = $station_no_str;
$station_setting['station_name'] = $station_name_str;
$station_setting['station_ip'] = $station_ip_str;
$station_setting['station_888'] = $station_888_str;
return $station_setting;
}
// ------------------------------------------------
//
// 中控接收端 (END)
//
// ------------------------------------------------
// ------------------------------------------------
//
// 其它 (START)
//
// ------------------------------------------------
// 手動新增入場資料
public function gen_carin($parms)
{
$in_time = date('Y-m-d H:i:s');
$data = array(
'station_no' => $parms['sno'],
'obj_type' => 1,
'obj_id' => $parms['lpr'],
'etag' => '',
'in_out' => $parms['io'],
'finished' => 0,
'in_time' => $in_time,
'in_lane' => $parms['ivsno'],
'out_before_time' => $in_time
);
$this->db->insert('cario', $data);
trigger_error("新增入場資料:".print_r($parms, true));
require_once(ALTOB_SYNC_FILE);
// 傳送進場記錄
$sync_agent = new AltobSyncAgent();
$sync_agent->init($parms['sno'], $in_time);
$sync_agent->cario_no = $this->db->insert_id(); // 進出編號
$sync_result = $sync_agent->sync_st_in($parms);
trigger_error( SYNC_DATA_LOG_TITLE . '..'. __FUNCTION__ . "..sync_st_in.." . $sync_result);
}
// ------------------------------------------------
//
// 其它 (END)
//
// ------------------------------------------------
}

+ 127
- 0
models/Txdata_model.php 파일 보기

@@ -0,0 +1,127 @@
<?php
/*
file: Txdata_model.php 交易資訊系統
*/
class Txdata_model extends CI_Model
{
var $mcache;
var $mqtt;
function __construct()
{
parent::__construct();
$this->load->database();
$this->now_str = date('Y-m-d H:i:s');
}
public function init($vars)
{
$this->mcache = $vars['mcache'];
$this->mqtt = $vars['mqtt'];
}
// 取得所有場站有效費率
public function get_all_valid_price_plan($station_no)
{
$result = $this->db->select('tx_price_plan_id as txid, tx_type, station_no, remarks, price_plan, start_time, valid_time, create_time')
->from('tx_price_plan')
->where(array(
'start_time <= ' => $this->now_str,
'valid_time > ' => $this->now_str,
'station_no' => $station_no
))
->get()
->result_array();
return $result;
}
// 取得場站費率設定
// http://203.75.167.89/txdata.html/get_price_plan/12112/0
public function get_price_plan($station_no, $tx_type)
{
$result = $this->db->select('price_plan')
->from('tx_price_plan')
->where(array(
'start_time <= ' => $this->now_str,
'valid_time > ' => $this->now_str,
'station_no' => $station_no,
'tx_type' => $tx_type
))
->get()
->result_array();
return $result;
}
// 取得特殊日期設定
// http://203.75.167.89/txdata.html/get_date_plan/12345678/23456789
public function get_date_plan($inTime, $balanceTime)
{
$inDateTimestamp = strtotime(date("Y-m-d", $inTime));
$balanceDateTimestamp = strtotime(date("Y-m-d", $balanceTime));
$result = $this->db->select('p_type, p_date')
->from('tx_date_plan')
->where("p_date BETWEEN FROM_UNIXTIME({$inDateTimestamp}) AND FROM_UNIXTIME({$balanceDateTimestamp})")
//->where("p_date BETWEEN '{$inDate}' AND '{$outDate}'")
->get()
->result_array();
return $result;
}
// 同步場站費率
public function sync_price_plan()
{
try{
$param = array('station_no' => STATION_NO);
// 查另一台主機
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://61.219.172.11:60123/admins.html/price_plan_query');
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,5);
curl_setopt($ch, CURLOPT_TIMEOUT, 5); //timeout in seconds
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($param));
$data = curl_exec($ch);
curl_close($ch);
}catch (Exception $e){
trigger_error('error msg:'.$e->getMessage());
}
$decode_result = json_decode($data, true);
if (sizeof($decode_result) <= 0) return "empty";
$this->db->trans_start();
foreach ($decode_result as $key => $value)
{
$station_no = $value["station_no"];
$tx_price_plan_id = $value["txid"];
$tx_type = $value["tx_type"];
$price_plan_data = array
(
'station_no' => $station_no,
'tx_type' => $tx_type,
'remarks' => $value['remarks'],
'price_plan' => $value['price_plan'],
'start_time' => $value['start_time'],
'valid_time' => $value['valid_time']
);
// 刪除
$this->db->delete('tx_price_plan', array('station_no' => $station_no, 'tx_type' => $tx_type));
// 新增
$this->db->insert('tx_price_plan', $price_plan_data);
}
$this->db->trans_complete();
return "ok";
}
}

+ 76
- 0
models/User_model.php 파일 보기

@@ -0,0 +1,76 @@
<?php
/*
file: User_model.php 管理登入系統
*/
class User_model extends CI_Model
{
function __construct()
{
parent::__construct();
$this->load->database();
}
// 登入
public function user_login($data)
{
$login_name = $data['login_name'];
$pswd = $data['pswd'];
$this -> db -> select('login_name, user_type, status');
$this -> db -> from('users');
$this -> db -> where('login_name', $login_name);
$this -> db -> where('pswd', MD5($pswd));
$this -> db -> where('status', 1); // '狀態, 1:正常, 2:暫時停權, 3:永久停權'
$this -> db -> limit(1);
$query = $this -> db -> get();
if($query -> num_rows() == 1)
{
return $query->result();
}
else
{
return false;
}
}
// 新增
public function user_insert($data)
{
$data['status'] = 1; // '狀態, 1:正常, 2:暫時停權, 3:永久停權'
$this->db->insert('users', $data);
return true;
}
// 修改
public function user_update($data, $target_name)
{
$this->db->update('users', $data, array('login_name' => $target_name));
return true;
}
// 查詢
public function user_query()
{
$results = $this->db->select('login_name, user_name, status, modify_time, user_type')
->from('users')
->where(array('user_type' => 'user')) // 'admin:最高管理者, user:用戶'
->order_by('modify_time', 'desc')
->get()
->result_array();
return $results;
}
// 刪除
public function user_delete($login_name)
{
$this->db->delete('users', array('login_name' => $login_name));
return true;
}
}

+ 11
- 0
models/index.html 파일 보기

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<p>Directory access is forbidden.</p>
</body>
</html>

불러오는 중...
취소
저장