天天看點

PHP語言對接中控考勤機實作打卡推送

我選的架構是tp5.1

考勤機型号:中控M880。固件版本:ver 6.5.4(build162)

制造商:ZKTECO Inc

mcu ver 27

push 2.32

camera ver V2.0,c2

push文檔擷取:公衆号搜尋  霖深時見露 回複  push文檔  擷取

幾個要點,做這個功能的肯定都有push文檔。第一個路由對應到。  iclock/cdata。構造一個這樣的路由。apache下,可以選擇重寫,也可以選擇route改變路由。nginx下重寫一下路由。基本就可以了。下面貼代碼:

Cdata.php

<?php
namespace app\iclock\controller;
use think\Controller;
use think\facade\Request;
use app\iclock\model\Mechine;
use app\iclock\model\Checklog;
use think\facade\Log;
use app\iclock\model\Cmds;
//use app\mobile\controller\Pushcheck;

class Cdata extends Controller
{
    public function login()
    {    


        //exit;
            $flag = json_encode(Request::param());
            $sn = Request::param('SN');
             file_put_contents('log.txt',$flag.PHP_EOL,FILE_APPEND);
            //1.判斷考勤機是否存在
            $res = Mechine::where('sn',$sn)->find();
            if($res)
            {
                //存在,先更新考勤機資訊
                Mechine::where('sn',$sn)->update(['update_time'=>time()]);
                if(Request::param('options') == 'all')
                {    
                    //首次接收考勤機發來的消息
                    $return     = "GET OPTION FROM : {$sn}";
                    $array = [
                    'Stamp' => time(),
                    'OpStamp' => time(),
                    'PhotoStamp' => time(),
                    'ErrorDelay' => 30,
                    'Delay' => 30,
                    'TransFlag' => '0000000000',
                    'Realtime' => 1,
                    'TransInterval'=>0,
                    'Encrypt' => 0,
                    'ServerVer' => '2.32 '.date('Y-m-d'),
                    'ATTLOGStamp' => time(),
                    'ATTPHOTOStamp'=>time(),
                    ];
                    $unix_time  = date_default_timezone_set('GMT');
                    header("HTTP/1.0 200 OK");
                    header("Content-Type: text/plain");
                    header("Date:".$unix_time);
                    $string = "";
                    foreach ($array as $key => $val)
                    $return .= $key .'='.$val.PHP_EOL;
                    return $return;
                }
                else
                {  
                    if(Request::param('table') == 'ATTLOG')
                    {    
                    //擷取刷卡時間和卡号
                    $stamp = json_encode(Request::param('Stamp'));
//                    file_put_contents('ATTLOG.txt',$stamp.PHP_EOL,FILE_APPEND);
                    $text = json_encode(file_get_contents("php://input"));
                    file_put_contents('ATTLOG1.txt',$text.PHP_EOL,FILE_APPEND);
    return "ok";
                    }
                    elseif(Request::param('table') == 'OPERLOG')
                    {
                    $stamp = json_encode(Request::param());
                    //file_put_contents('OPERLOG.txt',$stamp.PHP_EOL,FILE_APPEND);
                    $text = json_encode(file_get_contents("php://input"));
                  
                   // file_put_contents('OPERLOG1.txt',$text.PHP_EOL,FILE_APPEND);
                    return "ok";
                    }
                    elseif(Request::param('table') == 'ATTPHOTO')
                    {
                        $text = file_get_contents("php://input");
                        file_put_contents('1111a.txt',$text,FILE_APPEND);
                        $str2 = substr($text,68);
                        $filepath = 'attendance/';
                        if(!is_dir($filepath))mkdir($filepath,0777,true);
                        $filename=$filepath.time().'.jpg';
                        $tmp = explode('.jpg', $text);
                        $pin = explode('-', $tmp[0]);
                        $checktimetmp = $pin[0];
                        $checktime = explode('=', $checktimetmp);
                        $checktime = strtotime($checktime[1]);
                        //pin:使用者工号
                        $pin = $pin[1];
                        if($pin){  //使用者驗證通過
                            //sn:裝置号
                            $sntmp = explode('=', $text);
                            $sn = str_replace('size', '', $sntmp[2]);
                            $checklog = model('Checklog')->get(['pin'=>$pin,'checktime'=>$checktime,'sn'=>$sn]);
                            if($checklog){
                                return iconv("UTF-8", "GB2312//IGNORE", 'ok');
                            }else{
                                file_put_contents($filename,$str2);
                                file_put_contents('ATTPHOTO1.txt',$str2.PHP_EOL,FILE_APPEND);
                                $info = Cmds::get(function($query) use ($pin){
                                    $query->where(['pin'=>$pin,'status'=>1])->order('update_time desc')->field('card,student_name');
                                });
                                $card = $info->card;
                                $student_name = $info->student_name;
                                $model = new Checklog();
                                $rs = $model->save(['pin'=>$pin,'checktime'=>$checktime,'pic'=>$filename,'sn'=>$sn,'card'=>$card,'student_name'=>$student_name]);
                                if(!$rs){
                                    $rs = $model->save(['pin'=>$pin,'checktime'=>$checktime,'pic'=>$filename,'sn'=>$sn,'card'=>$card,'student_name'=>$student_name]);
                                }
                                //推送考勤資訊
//                                $this->sendTempletemsg($model->id);
                                $this->https_request('https://'.config('domain').'/mobile/pushcheck/sendTempletemsg?checkid='.$model->id);

                            }
                            return iconv("UTF-8", "GB2312//IGNORE", 'ok');
                        }

                     /*結束*/
                    }
                }
            }
            else
            {  
                //不存在,寫入考勤機資訊
               $data = ['sn' => $sn,'options'=>$flag,'create_time'=>time()];
               Mechine::insert($data);
            }
       
    }
    function get_contents() {     
        $xmlstr = file_get_contents('php://input')?file_get_contents('php://input') : gzuncompress($GLOBALS['HTTP_RAW_POST_DATA']);//得到post過來的二進制原始資料    
        $filename=time().'.png';    
        if(file_put_contents($filename,$xmlstr)){    
        echo 'success';    
        }else{    
        echo 'failed';    
        }

    }
    //兩個字元串之間的字元串
    public function str_between(){
        $str = 'DATA UPDATE USERINFO PIN=1\tName=測試2\tPasswd=123456\tPri=14\tsCard=[1985100]';
        $str1 = 'Name=';
        $str2 = '\tPasswd';
        $start = mb_strpos($str,$str1)+mb_strlen($str1);
        $end = mb_strpos($str,$str2);
        $length = $end-$start;
        dump($length);
        $needle = mb_substr($str,$start,$length,'utf8');
        dump($needle);
        return $needle;
    }



    //發送考勤打卡推送模闆消息
    public function sendTempletemsg($checkid){
//        $checkid = input('param.checkid');  //考勤打卡id
        $checkinfo = Checklog::get(intval($checkid));  //考勤打卡資訊
        if(!$checkinfo)return;
        $card_sn = $checkinfo->card;  //卡号
        $user = model('user')->get(array('card_sn'=>$card_sn)); //根據卡号查找學生資訊
        if(!$user)return;
        $user_id = $user->id;
        $parentinfo = model('wxuser')->all(array('user_id'=>intval($user_id))); //查詢綁定了該學生的所有家長老師
        $access_token = $this->getWXToken();
        $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$access_token;
        foreach ($parentinfo as $key=>$value){
            $openid = $value->openid;
            $data = array(
                "touser"=>$openid,
                "template_id"=>"Y44crAtSKT47r8Cd5mnCM844vn7Iw6uVvU2Dq7p2tng",
                'url'=>'http://'.config('domain').'/'.$checkinfo->pic,
                'data'=>array(
                    'first'=>array(
                        'value'=>'您好,您有一條考勤消息提醒!',
                        'color'=>'#41495e'
                    ),
                    'keyword1'=>array(
                        'value'=>$user['real_name'], //學生姓名
                    ),
                    'keyword2'=>array(
                        'value'=>date('Y-m-d H:i:s',$checkinfo->checktime),    //打卡時間
                    ),
                    'keyword3'=>array(
                        'value'=>$checkinfo->status,    //考勤狀态
                    ),
                    'keyword4'=>array(
                        'value'=>$checkinfo->card,    //接送卡号
                    ),
                    'keyword5'=>array(
                        'value'=>$checkinfo->address,    //地點
                    ),
                    "remark"=>array(
                        'value'=>"點選檢視考勤圖檔",
                        'color'=>'#41495e'
                    )
                )
            );
            $result = $this->https_request($url,json_encode($data));
            $result = json_decode($result,true);
            if($result['errcode'] == 0){
                //儲存推送通知
                $model = new Checklog();
                $model->save(['pushstate'=>1],['id'=>$checkid]);
                return true;
            }else{
                //推送失敗 TODO
                return false;
            }
        }
    }
    //擷取微信access_token
    public function getWXToken(){
        // error_reporting(E_ERROR | E_WARNING | E_PARSE);
        // $wxconfig = config('wxconfig');
        // $cache_file = dirname(__FILE__).'/../../../access_token.json';
        // if(file_exists($cache_file)) $info = json_decode(file_get_contents($cache_file),true);
        // if($info['access_token'] && $info['expire_time']>time()){
        //     return $info['access_token'];
        // }
        // $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$wxconfig['appid'].'&secret='.$wxconfig['appsecret'];
        // $result = $this->https_request($url);
        // $data = json_decode($result,true);
        // if($data['access_token']){
        //     $arr = array();
        //     $arr['access_token'] = $data['access_token'];
        //     $arr['expire_time'] = time() + 7000;
        //     file_put_contents($cache_file,json_encode($arr));
        //     return $data['access_token'];
        // }
        // else return '';
    }
    //https請求(支援GET和POST)
    public function https_request($url, $data = null){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
}
           

getrequest.php

<?php
namespace app\iclock\controller;

use think\Controller;
use think\facade\Request;
use app\iclock\model\Cmds;

class Getrequest extends Controller
{
    public function login(){
        $sn = Request::param('SN');
        // file_put_contents('log111.txt',$sn.PHP_EOL,FILE_APPEND);
//        $check = Cmds::where('id',11)->find();
        $check = Cmds::where('c_name','like','%DATA UPDATE USERINFO%')->where('status',0)->order('id asc')->find();
        if(!$check)return false;
        //轉換卡号,發送指令
        $c_name = $this->changecard($check['c_name']);
        if($check['status'] == '0' && $check['sn'] == $sn) {
            $unix_time  = date_default_timezone_set('GMT');
            header("HTTP/1.0 200 OK");
            header("Content-Type: text/plain");
            header("Date:".$unix_time);
            $cmd = "C:{$check['c_id']}:{$c_name}".PHP_EOL;
            Cmds::where('id',$check['id'])->update(['update_time'=>time(),'status'=>1]);
            //把CMD的指令
            $gbkcmd = iconv("UTF-8", "GB2312//IGNORE", $cmd);
            return $gbkcmd;
             // "C:10:DATA UPDATE USERINFO cardno=0001985100\tpin=32\tpassword=123\tgroup=0\tstarttime=0\tendtime=0\tname=mike\tsuperauthorize=0\tdisable=0".PHP_EOL
        }
    }

    //轉換卡号為16進制後重新組合
    public function changecard($c_name){
        $card = explode('sCard=',$c_name);
        $tmpc_name = $card[0];
        $card = str_replace('[', '', $card[1]);
        $card = dechex(str_replace(']', '', $card));    //轉換成16進制
        $str1 = substr($card, 0,2);
        $str2 = substr($card, 4,2);
        $str3 = substr($card, 2,2);
        $card = $str2.$str3.$str1;  //重新排列後的卡号
        $c_name = $tmpc_name.'sCard=['.$card.'0000]';
        $c_name = str_replace('\t',iconv("UTF-8", "GBK//IGNORE", "\t") , $c_name);
        return $c_name;
    }
    public function hello($name = 'ThinkPHP5'){
        return 'hello,' . $name;
    }
    public function test(){
        $check = Cmds::where('c_name','like','%DATA UPDATE USERINFO%')->where('status',0)->order('id asc')->find();
        dump($check);
    }
}
           

devidecmd.php

<?php
namespace app\iclock\controller;

use think\Controller;
use think\facade\Request;

class Devicecmd extends Controller
{
    public function index()
    {

        $text = file_get_contents("php://input");
        if(stristr($text,'Return=0'))
        {
            $text = json_encode($text);
            file_put_contents('logcmd.txt', $text . PHP_EOL, FILE_APPEND);
            $unix_time = date_default_timezone_set('GMT');
            header("HTTP/1.1 200 OK");
            header("Content-Type: text/plain");
            header("Date:" . $unix_time);
//            $cmd = "C:1:SHELL CMD_STRING".PHP_EOL;
//            return $cmd;
            return 'OK';
        }



        



    }

    public function hello($name = 'ThinkPHP5')
    {
        return 'hello,' . $name;
    }
}
           

之後的邏輯可以自己按需求來寫