yzms/show/api_pos.php

571 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?
require_once(dirname(__FILE__)."/common.php");
$qs = $_SERVER['QUERY_STRING'];
$json = file_get_contents("php://input");
$post = json_decode($json, true, 512 , JSON_BIGINT_AS_STRING);
$serialno = $post['serialno'];
if(!$serialno) exit;
$deviceInfo = $db->get_one("select * from tb_pos_device where serialno = '".addslashes($serialno)."'");
$device_id = intval($deviceInfo['id']);
$ip = $_SERVER["REMOTE_ADDR"];
$s1 = $json;
if(strlen($s1) > 2000) {
$s1 = substr($s1, 0, 2000).'..';
}
$db->query("insert into tb_pos_device_log set device_id = {$device_id}, serialno = '".addslashes($serialno)."', ip = '".addslashes($ip)."', path = '".addslashes($qs)."', request = '".addslashes($s1)."', response = '', addtime = now() ");
$log_id = $db->insert_id();
if(!$deviceInfo) {
$db->query("update tb_pos_device_log set response='no_device' where id=".$log_id);
exit;
}
$company_id = intval($deviceInfo['company_id']);
$dining_hall_id = intval($deviceInfo['dining_hall_id']);
$channel_id = intval($deviceInfo['channel_id']);
$sign2 = md5($post['time'].$post['noncestr'].$deviceInfo['cardpwd']);
if($sign2 !== $post['sign']) { //签名错误
$db->query("update tb_pos_device_log set response='sign_err' where id=".$log_id);
exit;
}
function response_pos($api, $data) {
global $deviceInfo, $post, $log_id, $db;
$noncestr = md5(microtime().'_'.rand());
$time = time();
$sign = md5($time.$noncestr.$deviceInfo['cardpwd']);
$data['sign'] = $sign;
$data['api'] = $api;
$data['interval'] = '10000';
$data['transaction_id'] = $post['transaction_id']?$post['transaction_id']:"100";
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
$db->query("update tb_pos_device_log set response='".addslashes($json)."' where id=".$log_id);
echo $json;
exit;
}
function self_query($path, $post) {
return gquery("http://127.0.0.1:".$_SERVER['SERVER_PORT'].$path, $post, array('Host: '.$_SERVER['SERVER_NAME']));
}
function pos_check_user() {
global $post, $db, $company_id;
$pay_mode = $post['params']['pay_mode'];
$pay_code = $post['params']['pay_code'];
if($pay_mode == '5') { //二维码
$qr_code = trim($post['params']['qr_code']);
if(!$qr_code) exit;
if(substr($qr_code, 0, 4) != '[st]' || substr($qr_code, -1) != ';') exit;
$s = substr($qr_code, 4, -1);
$a = explode(",", $s);
if(count($a) != 2) exit;
$code = $a[0];
$hash = $a[1];
return array('type' => 'qr', 'code' => $code);
}
if(strpos($pay_code, 'yzms_') !== 0) exit;
$uid = intval(substr($pay_code, 5));
$uInfo = $db->get_one("select * from tb_user where id = '{$uid}' and enabled != '0' and company_id=".$company_id);
if(!$uInfo) {
$arr = array (
'result_code' => '2',
'result_msg' => "err", //10寸屏蔽失败时界面显示此内容result_code=2
'tts' => "用户不存在", //语音播报为空时不报TTS语音
'result' => array (), //服务器返回结果数据,查询信息无
'timeout' => '5', //取餐超时时间,秒为单位,注:特殊修改机型才有此功能
'msg' => array (array ('line' => '用户不存在!',)),
);
response_pos($post['api'], $arr);
}
return $uInfo;
}
if($qs == 'heartbeat' || $qs == 'addperson' || $qs == 'delperson') { //心跳
if($qs == 'addperson' && $post['whitelist']) {
foreach($post['whitelist'] as $item) {
$uid = intval(str_replace('yzms_', '', $item['account_id']));
$rec_id = intval($item['rec_id']);
$db->query("update tb_pos_device_user set status=2,rs='".$item['result_code']."' where id = '{$rec_id}' and uid = '{$uid}'");
}
}
if($qs == 'delperson' && $post['whitelist']) {
foreach($post['whitelist'] as $item) {
$uid = intval(str_replace('yzms_', '', $item['account_id']));
$rec_id = intval($item['rec_id']);
$db->query("delete from tb_pos_device_user where id = '{$rec_id}' and uid = '{$uid}'");
}
}
if($qs != 'heartbeat' || (time() - strtotime($deviceInfo['synctime']) > 60)) { //1分钟检测一次用户同步
$db->query("update tb_pos_device set synctime=now() where id = ".$device_id);
$userList_s = $db->get_all("select id, username, cellphone, deptname from tb_user where enabled = '1' and company_id = '{$company_id}'");
$userList_d = $db->get_all("select * from tb_pos_device_user where device_id = '{$device_id}'");
$data = $db->get_all("select a.* from tb_user_face a, tb_user b where a.user_id=b.id and b.company_id = '{$company_id}'");
$faceInfo = array();
foreach($data as $item) {
if(is_file("../backstage/".$item['path'])) {
$faceInfo[$item['user_id']] = $item;
}
}
$data = $db->get_all("select a.* from tb_user_idcard a, tb_user b where a.user_id=b.id and b.company_id = '{$company_id}' and a.state=1 order by a.id");
$cardInfo = array();
foreach($data as $item) {
$cardInfo[$item['user_id']] = $item;
}
foreach($userList_s as $key => $item) {
$uid = $item['id'];
$info1 = $faceInfo[$uid];
$userList_s[$key]['facecode'] = $info1['facecode'].'';
$userList_s[$key]['facepath'] = $info1['path'].'';
$info1 = $cardInfo[$uid];
$userList_s[$key]['cardno'] = $info1['cardno'].'';
}
$sUserInfo = array();
foreach($userList_s as $item) {
$sUserInfo[$item['id']] = $item;
}
$dUserInfo = array();
foreach($userList_d as $item) {
$dUserInfo[$item['uid']] = $item;
}
$row = $db->get_one("select * from tb_config where class = 'HOST'");
$host = $row['value'];
$addList = array(); //增加列表
$maxcount = 100;
foreach($userList_s as $item) {
$uid = $item['id'];
if(!$dUserInfo[$uid]) {
$addList[] = $item;
if(count($addList) >= $maxcount) break; //限制一次20个
continue;
}
$item2 = $dUserInfo[$uid];
if(
($item2['facecode'].'') !== ($item['facecode'].'')
|| ($item2['cardno'].'') !== ($item['cardno'].'')
|| ($item2['username'].'') !== ($item['name'].'')
|| ($item2['cellphone'].'') !== ($item['cellphone'].'')
|| ($item2['deptname'].'') !== ($item['deptname'].'')
) {
$addList[] = $item;
if(count($addList) >= $maxcount) break;
continue;
}
if($item2['status'] == 1 && time()-strtotime($item2['sendtime']) > 300) { //距上次下发5分钟后还没收到确认
$addList[] = $item;
if(count($addList) >= $maxcount) break;
continue;
}
}
if($addList) {
$whitelist = array();
foreach($addList as $item) {
$uid = $item['id'];
$face_url = '';
if($item['facepath']) {
$face_url = 'https://'.$host.'/backstage/'.$item['facepath'];
}
$row1 = $db->get_one("select * from tb_pos_device_user where device_id = '".addslashes($device_id)."' and uid = '".addslashes($uid)."'");
$sqlext = " name = '".addslashes($item['username'])."', cellphone = '".addslashes($item['cellphone'])."', deptname = '".addslashes($item['deptname'])."', cardno = '".addslashes($item['cardno'])."', facecode = '".addslashes($item['facecode'])."', sendtime = now(), status = 1, rs = '' ";
if(!$row1) {
$db->query("insert into tb_pos_device_user set device_id = '".addslashes($device_id)."', uid = '".addslashes($uid)."', {$sqlext}, addtime = now() ", 'SILENT');
$log_id1 = $db->insert_id();
} else {
$db->query("update tb_pos_device_user set {$sqlext} where id=".$row1['id']);
$log_id1 = $row1['id'];
}
$whitelist[] = array (
'rec_id' => $log_id1.'', //可为数据库中的唯一id可以是字符串可以是整数可为空字符
'account_id' => 'yzms_'.$uid, //帐号唯一50个字符必填
'emp_id' => 'emp_'.$uid, //工号唯一50个字符必填
'emp_fname' => $item['username'], //姓名50个字符必填
'depart_name' => $item['deptname'], //部门50个字符必填
'job_name' => '', //职务仅10.1寸去向牌门禁机有效
'tel' => $item['cellphone'], //电话仅10.1寸去向牌门禁机有效
'sex' => '', //性别,可为空字符
'birth_date' => '', //出生日期,可为空字符
'valid_date' => '2099-01-01', //有效日期,必填
'level_id' => '1', //级别整数必须是整数必填用不到的话填0
'card_sn' => $item['cardno'], //卡序列号整数没有时用空字符注意卡号时前面不能有0
'door_right' => '', //门权限, 预留,没有时用空字符
'url' => $face_url, //个人相片的url地址可为空字符表示无相片
'groups' => '0', //组别为第3组长整型二进制时从最低位开始为1组0表示无1表示有例如第3组的二进制表示0000100转换为十进制则是4第3组的groups为4必填不需要时填0
'access_pwd' => '1234', //个人密码整数4位不足补0必填
'state' => '0', //整数状态0正常 2挂失只有刷卡时才会判断人脸不判断另离线时才判断在线由平台判断为整数不能非整数必填
'twins' => '', //注意固定为空!,必填
'retain_photo' => '0', //整数,下载个人相片处理方式, 仅url为空时才有效 = 0默认删除相片 、 =1保留相片还要识别必填无相片时统一此值用0当url有值时按url的值处理可以固定为0
'begin_date' => '2022-04-01 00:00:00',//开始时间
'end_date' => '2099-01-01 23:59:59', //结束时间
'time' => array (),
);
}
$arr = array (
'whitelist' => $whitelist,
);
response_pos('addperson', $arr);
exit;
}
$delList = array(); //删除列表
$maxcount = 100;
foreach($userList_d as $item) {
$uid = $item['uid'];
if($item['status'] == 4) {
if(time()-strtotime($item['sendtime']) > 300) { //距上次下发删除5分钟后还没收到确认
if($item['err_num'] < 3) {
$db->query("update tb_pos_device_user set sendtime = now(), status = 4, rs = '',err_num=err_num+1 where id=".$item['id']);
$delList[] = $item;
if(count($delList) >= $maxcount) break; //限制一次20个
} else {
$db->query("delete from tb_pos_device_user where id=".$item['id']);
}
}
continue;
}
if(!$sUserInfo[$uid]) {
$delList[] = $item;
if(count($delList) >= $maxcount) break; //限制一次20个
continue;
}
}
if($delList) {
$whitelist = array();
foreach($delList as $item) {
$log_id1 = $item['id'];
$uid = $item['uid'];
$whitelist[] = array (
'rec_id' => $log_id1.'', //服务器端数据库的唯一id
'account_id' => 'yzms_'.$uid, //帐号
'emp_id' => 'emp_'.$uid, //工号
'only_del_photo' => '0', //=0删除名单 =1名单不删除只删除个人相片
);
}
$arr = array (
'whitelist' => $whitelist,
);
response_pos('delperson', $arr);
exit;
}
}
$records = $post['records'];
$arr = array (
'setmname' => '',
);
if($records) {
$records2 = array();
foreach($records as $item) {
$records2[] = array('id' => $item['id']);
}
$arr['records'] = $records2;
}
response_pos('heartbeat', $arr);
}
else if($qs == 'real') {
$api = $post['api'];
if($api == 'takemeal' || $api == 'takemealok') { //取餐
$uInfo = pos_check_user();
$uid = $uInfo['id'];
function get_today_dates($dining_hall_id)
{
global $db;
$data = $db->get_all("select * from tb_date where dining_hall_id={$dining_hall_id} and dc_date = '".date("Y-m-d")."'");
$nowtime = date('H:i');
$all = array();
foreach($data as $item) {
$dc_type = $item['dc_type'];
$meal_info = $db->get_one("select * from tb_meal_type where status=1 and id=".intval($dc_type));
if( $nowtime >= $meal_info['start_time'] && $nowtime < $meal_info['end_time']) {
$all[] = $item;
}
}
return $all;
}
$dates = get_today_dates($dining_hall_id);
$order = '';
for($i = 1; $i <= 2; $i++) {
foreach($dates as $date) {
$sqlext = " uid = {$uid} ";
if($uInfo['type'] == 'qr') { //取餐码
$sqlext = " take_food_code = '".addslashes($uInfo['code'])."' ";
}
$row = $db->get_one("select * from tb_order where {$sqlext} and date_id=".$date['id']." and state_id =".($i==1?6:3));
if($row) {
$order = $row;
if($uInfo['type'] == 'qr') { //取餐码
$uInfo = $db->get_one("select * from tb_user where id = '".$order['uid']."'");
if(!$uInfo) exit;
$uid = $uInfo['id'];
}
break;
}
}
if($order) break;
}
if(!$order) {
if($uInfo['type'] == 'qr') { //取餐码
$arr = array (
'result_code' => '2',
'result_msg' => "err", //10寸屏蔽失败时界面显示此内容result_code=2
'tts' => "取餐码错误", //语音播报为空时不报TTS语音
'result' => array (), //服务器返回结果数据,查询信息无
'msg' => array (
array (
'line' => '取餐码错误',
),
),
'timeout' => '5', //取餐超时时间,秒为单位,注:特殊修改机型才有此功能
);
} else {
$arr = array (
'result_code' => '2',
'result_msg' => "err", //10寸屏蔽失败时界面显示此内容result_code=2
'tts' => "没有该时段的订餐记录", //语音播报为空时不报TTS语音
'result' => array (), //服务器返回结果数据,查询信息无
'msg' => array (
array (
'line' => '没有该时段的订餐记录',
),
array (
'line' => '姓名: '.$uInfo['username'],
),
array (
'line' => '手机号: '.$uInfo['cellphone'],
),
),
'timeout' => '5', //取餐超时时间,秒为单位,注:特殊修改机型才有此功能
);
}
response_pos($api, $arr);
}
$s = self_query("/api/order/take", array('take_code' => $order['take_food_code'], 'dining_hall_id' => $dining_hall_id, 'channelid' => $channel_id));
$rs = json_decode($s, true);
if($rs['status'] != 1) {
$message = '取餐失败';
if($rs['message']) $message = $rs['message'];
$arr = array (
'result_code' => '2',
'result_msg' => "err", //10寸屏蔽失败时界面显示此内容result_code=2
'tts' => $message, //语音播报为空时不报TTS语音
'result' => array (), //服务器返回结果数据,查询信息无
'timeout' => '5', //取餐超时时间,秒为单位,注:特殊修改机型才有此功能
'msg' => array (array ('line' => $message,)),
);
response_pos($api, $arr);
}
$takeInfo = $rs['data']['list'][0];
$detail = array();
foreach($takeInfo['order_detail'] as $item) {
$detail[] = array (
'menu' => $item['dish_name'],
'amount' => $item['dish_amount'],
);
}
$take_status = $takeInfo['take_status'];
$tts = '';
$result_msg = '';
$timeout = '5';
if($take_status == 1) {
$tts = ($api == 'takemealok'?($uInfo['username']."取餐成功"):"");
$result_msg = ($api == 'takemealok'?"取餐成功":"查询成功");
$timeout = ($api == 'takemealok'?"1":"10");
} else {
$tts = '您已取过餐';
$result_msg = '您已取过餐';
$timeout = '5';
}
$arr = array (
'result_code' => ($take_status==1?'0':'1'), //0成功 非0失败1表示已取餐也要显示菜品信息2其它失败
'result_msg' => $result_msg, //10寸屏蔽失败时界面显示此内容result_code=2
'tts' => $tts, //语音播报为空时不报TTS语音
'result' => array (), //服务器返回结果数据,查询信息无
'msg' => array (
array (
'line' => '订单号:'.$order['code'],
),
array (
'line' => '姓名: '.$uInfo['username'],
),
array (
'line' => '手机号: '.$uInfo['cellphone'],
),
),
'detail' => $detail,
'timeout' => $timeout, //取餐超时时间,秒为单位,注:特殊修改机型才有此功能
);
response_pos($api, $arr);
}
else if($api == 'infoquery') { //消费前查询用户
$uInfo = pos_check_user();
$uid = $uInfo['id'];
$row = $db->get_one("select sum( account ) as c from tb_account where user_id = '{$uid}'");
$arr = array (
'tts' => '',
'msg' => array (),
'balance' => '', //余额显示测试无效
'query_code' => '0', //注意取餐机时应答为1消费机时为0
'result_code' => '0',
'result' => array (
array (
'account_id' => '',
'consume' => '',
'balance' => round($row['c']*100).'',
'sign' => '',
'Corrections' => '',
)
),
'title' => '云中美食',
'emp_fname' => $uInfo['username'],
'result_msg' => '',
'detail' => array (),
);
response_pos('infoquery', $arr);
}
else if($api == 'posonline') { //消费
$uInfo = pos_check_user();
$uid = $uInfo['id'];
$amount = intval($post['params']['amount']);
if($amount <= 0) exit;
$amount = $amount/100;
$pay_mode = $post['params']['pay_mode']; // 0人脸 1云卡 2卡序列号 3取餐码 5二维码
$post = array('ftid' => $dining_hall_id, 'channelid' => $channel_id, 'fee' => $amount);
if($pay_mode == 0) { //0人脸
$row1 = $db->get_one("select * from tb_user_face where user_id = '{$uid}'");
if(!$row1) exit;
$post['type'] = 'face';
$post['code'] = $row1['card'];
} else if($pay_mode == 2) { //2卡序列号
$row1 = $db->get_one("select * from tb_user_idcard where user_id = '{$uid}' and state = '1'");
if(!$row1) exit;
$post['type'] = 'ic';
$post['code'] = $row1['cardno'];
} else if($pay_mode == 5) { //5付款码
if($uInfo['type'] != 'qr') exit;
$post['type'] = 'qr';
$post['code'] = $uInfo['code'];
} else {
exit;
}
$s = self_query("/api/user/qrpay", $post);
$rs = json_decode($s, true);
if($rs['status'] != 1) {
$message = '付款失败';
if($rs['message']) $message = $rs['message'];
$arr = array (
'result_code' => '2',
'result_msg' => "err", //10寸屏蔽失败时界面显示此内容result_code=2
'tts' => $message, //语音播报为空时不报TTS语音
'result' => array (), //服务器返回结果数据,查询信息无
'timeout' => '5', //取餐超时时间,秒为单位,注:特殊修改机型才有此功能
'msg' => array (array ('line' => $message,)),
);
response_pos($api, $arr);
}
if($uInfo['type'] == 'qr') {
$row1 = $db->get_one("select * from tb_payqr where code = '".addslashes($uInfo['code'])."'");
$uid = intval($row1['uid']);
$uInfo = $db->get_one("select * from tb_user where id = '".$uid."'");
}
$arr = array (
'result_code' => '0', //0成功7需要密码消费消费机出现输入密码的界面密码输入正确后消费机再次调用接口psd_state=1服务器收到为1时则消费成功其它失败
'result_msg' => '',
'result' => array (),
'tts' => $uInfo['username'].' 消费'.$amount.'元成功',
'timeout' => '10',
'msg' => array (
array (
'line' => '姓名: '.$uInfo['username'],
),
array (
'line' => '消费: '.$amount.'元',
),
array (
'line' => '余额: '.$rs['data']['balance'].'元',
),
),
);
response_pos('posonline', $arr);
}
}
else if($qs == 'takephoto') {
$arr = array (
'result_code' => '0', //0成功
'result_msg' => '',
'result' => array (),
);
response_pos('takephoto', $arr);
}