优化ctms-api语法、修复已知BUG;

主要修复ctms-api、dacms对PHP新版本的支持问题
This commit is contained in:
2025-07-13 19:37:42 +08:00
parent 65bbd06981
commit 037f274ec5
413 changed files with 107271 additions and 72326 deletions
+516
View File
@@ -0,0 +1,516 @@
<?php
/**
* @Author: fm453
* @Date: 2019-04-27 22:19:28
* @Last Modified by: fm453
* @Last Modified time: 2019-04-29 17:08:02
*/
/**
* 利用workerman制作的推送接口控制器(针对vcms的fm453_*系列应用)
*/
namespace frontend\controllers;
use Yii;
use yii\web\Controller;
use dataModel;
//必须添加这一句,以便引入dataModel外部类库
// 引用GateWay Client
require(__DIR__ . '/../../vendor/workerman/GatewayClient-3.0.0/Gateway.php');
// GatewayClient 3.0.0版本开始要使用命名空间
use GatewayClient\Gateway;
// 设置GatewayWorker服务的Register服务ip和端口
Gateway::$registerAddress = '127.0.0.1:4530';
class PushimmsController extends Controller
{
public $enableCsrfValidation = FALSE;//取消对POST数据的csrf令牌验证
/**
* 绑定客户端与指定客户id\分组id
*/
public function actionBind()
{
global $_FM;
//数据取出方法
$dataGet = $_FM['get']; //GET进来的参数
$dataPost = $_FM['post']; //POST进来的参数
$data = array();
header('Access-Control-Allow-Origin:*'); //允许任何网站通过ajax发送请求
require dirname(__FILE__) . '/_public/plat.php';
$group_pre = 'VCMS-IMMS';
//前台已经建立起长链接,取得了客户端ID号;需要绑定到当前用户,并返回用户uid,供服务侧同步绑定校验
$viaDomain = fmFunc_server_via_domain(); //来路域名
$viaIP = fmFunc_server_via_ip(); //来路IP
$timestamp = isset($_FM['timestamp']) ? $_FM['timestamp'] : time();
//通过前端GET传入的
$client_id = isset($dataGet['client_id']) ? $dataGet['client_id'] : 0;
$accessToken = isset($dataGet['accesstoken']) ? $dataGet['accesstoken'] : 0;
//判断accesstoken有效性
/*
@有效性规则判断
*Yii::$app->user->identity->username,Yii::$app->user->identity->id 当前用户账号及id
*domain 域名匹配
*expiretime 有效期判断
*$_FM['apiCert'] 服务器证书
*/
$connection = yii::$app->db;
$sql = "SELECT `username` FROM c_access WHERE accesstoken = :accesstoken AND domain = :domain AND expiretime > :expiretime ORDER BY id ASC";
$params = array();
$params[':accesstoken'] = $accessToken;
$params[':domain'] = $viaDomain;
$params[':expiretime'] = $timestamp;
$result = fmFunc_pdo_yii_fetch($connection, $sql, $params);
if ($result) {
$username = $result['username'];
//加载证书文件,但无用户登陆状态
$cert = $username . '.php';
if (file_exists($_HI['apiCertPath'] . $cert)) {
$_FM['apiCert'] = array_merge(include($_HI['apiCertPath'] . $cert));
}
}
$_FM['apiCert']['token'] = $accessToken;
//处理POST数据
$client_type = isset($dataPost['client_type']) ? $dataPost['client_type'] : 'undefined';
$isWeb = ($client_type == 'web') ? TRUE : FALSE;
$isApp = ($client_type == 'app') ? TRUE : FALSE;
$isAppWeb = ($client_type == 'appweb') ? TRUE : FALSE;
$group_ids = array();
//根据当前用户身份生成可准确识别的用户ID
$uid = isset($dataPost['uid']) ? $dataPost['uid'] : 'undefined';
$uid = fmFunc_server_hash_id($uid);
// client_id与uid绑定
Gateway::bindUid($client_id, $uid);
$group_id = isset($dataPost['groupid']) ? $dataPost['groupid'] : 0;
if ($group_id) {
$group_ids[0] = $group_pre . fmFunc_server_hash_id(0);;
// 加入某个群组(可调用多次加入多个群组)
Gateway::joinGroup($client_id, $group_id); //当前用户所在的会员组
}
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
// 加入某个群组(可调用多次加入多个群组)
Gateway::joinGroup($client_id, $group_id); //当前用户所在的会员组
//继续根据创建更多分组
$do = isset($dataPost['do']) ? $dataPost['do'] : 'undefined';
$ac = isset($dataPost['ac']) ? $dataPost['ac'] : 'undefined';
$op = isset($dataPost['op']) ? $dataPost['op'] : 'undefined';
if ($isWeb) {
$type = 'web';
$group_id = $type . '_' . $do . '_' . $ac . '_' . $op;
$group_id = $group_pre . $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id);
$group_id = $type . '_' . $do . '_' . $ac;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id);
$group_id = $type . '_' . $do;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id);
} else {
$type = 'app';
$group_id = $type . '_' . $do . '_' . $ac . '_' . $op;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id);
$group_id = $type . '_' . $do . '_' . $ac;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id);
$group_id = $type . '_' . $do;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id);
$group_id = $type;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id); //当前用户并入前台用户组
if ($isAppWeb) {
$type = 'appweb';
$group_id = $type;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
$group_ids[$group_id] = $group_id;
Gateway::joinGroup($client_id, $group_id); //当前用户并入前台核销用户组
}
}
//发送反馈消息
$message = array();
$message = '棒,客户端绑定成功!';
$data = array();
$data['type'] = 'tips';
$data['msg'] = $message;
$data['groupids'] = $group_ids;
$data = json_encode($data);
Gateway::sendToClient($client_id, $data);
return;
}
/**
* 接收客户端数据
*/
public function actionIn()
{
$group_pre = 'VCMS-IMMS';
header('Access-Control-Allow-Origin:https://vcms.hiluker.com'); //允许指定网站通过ajax发送请求
// 建立socket连接到内部推送端口
$client = stream_socket_client('tcp://127.0.0.1:4530');
//如果用户已经登陆,uid和群组id存在
//TBD 构建uid、group_id的生成方式
$uid = isset($dataPost['uid']) ? $dataPost['uid'] : 0;
$group_id = isset($dataPost['group']) ? $dataPost['group'] : 0;
//$client_id 通过前端传入
$client_id = isset($dataGet['client_id']) ? $dataGet['client_id'] : 0;
// 推送的数据,包含uid字段,表示是给这个uid推送
$uid = isset(Yii::$app->user->identity->username) ? Yii::$app->user->identity->username : '0';
$data = array('uid' => $uid, 'msg' => urlencode('嗯,这个是测试用的'));
// 发送数据,注意该端口是Text协议的端口,Text协议需要在数据末尾加上换行符
fwrite($client, json_encode($data) . "\n");
// 读取推送结果
// echo '$client=='.$client;
//echo fread($client, 8192);
}
/**
* 向客户端推送消息
*/
public function actionOut()
{
global $_FM;
//数据取出方法
$dataGet = $_FM['get']; //GET进来的参数
$dataPost = $_FM['post']; //POST进来的参数
$params = Yii::$app->params;
// header('Access-Control-Allow-Origin:https://vcms.hiluker.com'); //允许指定网站通过ajax发送请求
header('Access-Control-Allow-Origin:*'); //允许指定网站通过ajax发送请求
require dirname(__FILE__) . '/_public/plat.php';
$group_pre = 'VCMS-IMMS';
/*设置REDIS缓存*/
//初始化$cache = new \Redis();
$cache = new \Redis();
$cache->connect($params['redis']['IP'], $params['redis']['PORT']);
// 先检查是否存在,然后写入并设置有效时间
$key = 'FmWebSorcketCount';
$CACHE_PREFIX = 'DACMS';
$count = 0;
if ($cache->exists($CACHE_PREFIX . $key)) {
// 读取
$count = $cache->get($CACHE_PREFIX . $key);
//清除
$cache->delete($CACHE_PREFIX . $key);
}
$cache->set($CACHE_PREFIX . $key, $count + 1);
$expire = time() + 604800; //一周时间再过期
$cache->expire($CACHE_PREFIX . $key, $expire);
//前台已经建立起长链接,取得了客户端ID号;需要绑定到当前用户,并返回用户uid,供服务侧同步绑定校验
$viaDomain = fmFunc_server_via_domain(); //来路域名
$viaIP = fmFunc_server_via_ip(); //来路IP
$timestamp = isset($_FM['timestamp']) ? $_FM['timestamp'] : time();
//通过前端GET传入的
$client_id = isset($dataGet['client_id']) ? $dataGet['client_id'] : '7f000001b0f400000010';
$accessToken = isset($dataGet['accesstoken']) ? $dataGet['accesstoken'] : 0;
//判断accesstoken有效性
/*
@有效性规则判断
*Yii::$app->user->identity->username,Yii::$app->user->identity->id 当前用户账号及id
*domain 域名匹配
*expiretime 有效期判断
*$_FM['apiCert'] 服务器证书
*/
$connection = yii::$app->db;
$sql = "SELECT `username` FROM c_access WHERE accesstoken = :accesstoken AND domain = :domain AND expiretime > :expiretime ORDER BY id ASC";
$params = array();
$params[':accesstoken'] = $accessToken;
$params[':domain'] = $viaDomain;
$params[':expiretime'] = $timestamp;
$result = fmFunc_pdo_yii_fetch($connection, $sql, $params);
$hasToken = FALSE;
$hasCert = FALSE;
if ($result) {
$username = $result['username'];
$hasToken = TRUE;
//加载证书文件,但无用户登陆状态
$cert = $username . '.php';
if (file_exists($_HI['apiCertPath'] . $cert)) {
$_FM['apiCert'] = array_merge(include($_HI['apiCertPath'] . $cert));
$hasCert = TRUE;
}
}
$_FM['apiCert']['token'] = $accessToken;
//处理POST数据
$client_type = isset($dataPost['client_type']) ? $dataPost['client_type'] : '';
$msg_type = isset($dataPost['msg_type']) ? $dataPost['msg_type'] : '';
if (!$msg_type) {
$msg_type = isset($dataGet['msg_type']) ? $dataGet['msg_type'] : '';
}
$isWeb = ($client_type == 'web') ? TRUE : FALSE;
$isApp = ($client_type == 'app') ? TRUE : FALSE;
$isAppWeb = ($client_type == 'appweb') ? TRUE : FALSE;
$msg = isset($dataPost['msg']) ? $dataPost['msg'] : '';
if (!$msg) {
$msg = isset($dataGet['msg']) ? $dataGet['msg'] : '';
}
//构造反馈消息
$data = array();
$data['type'] = $msg_type;
$data['msg'] = $msg;
if (isset($dataGet['debug'])) {
//向全体推送数据
$data['msg'] = empty($data['msg']) ? '第' . $count . '次测试群发' : $data['msg'];
$count++;
$data = json_encode($data);
Gateway::sendToAll($data);
return;
}
$data = json_encode($data);
//根据情况发送消息
switch ($hasToken) {
case TRUE:
//根据当前用户身份生成可准确识别的用户ID
$uid = isset($dataPost['uid']) ? $dataPost['uid'] : '';
if ($uid) {
$uid = fmFunc_server_hash_id($uid);
Gateway::sendToUid($uid, $data);
}
//有证书时,可继续下一步的推送
if (!$hasCert) {
break; //无证书,不再继续
}
//已指派分组时
$group_id = isset($dataPost['group']) ? $dataPost['group'] : 0;
if ($groud_id) {
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
Gateway::sendToGroup($group_id, $data);
break; //执行后结束此次推送
}
//根据创建更多分组
$do = isset($dataPost['do']) ? $dataPost['do'] : '';
$ac = isset($dataPost['ac']) ? $dataPost['ac'] : '';
$op = isset($dataPost['op']) ? $dataPost['op'] : '';
if ($client_type) {
if ($isWeb) {
$type = 'web';
} else if ($isAppWeb) {
$type = 'appweb';
} else {
$type = 'app';
}
if ($do) {
if ($ac) {
if ($op) {
$group_id = $type . '_' . $do . '_' . $ac . '_' . $op;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
Gateway::sendToGroup($group_id, $data);
} else {
$group_id = $type . '_' . $do . '_' . $ac;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
Gateway::sendToGroup($group_id, $data);
}
} else {
$group_id = $type . '_' . $do;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
Gateway::sendToGroup($group_id, $data);
}
} else {
$group_id = $type;
$group_id = $group_pre . fmFunc_server_hash_id($group_id);
Gateway::sendToGroup($group_id, $data);
}
}
break;
case FALSE;
//只发送给指定客户端
Gateway::sendToClient($client_id, $data);
break;
}
}
/**
* 接收客户端数据并向全部客户端群发
*/
public function actionSend2all()
{
// header('Access-Control-Allow-Origin:https://vcms.hiluker.com'); //允许指定网站通过ajax发送请求
header('Access-Control-Allow-Origin:*'); //允许指定网站通过ajax发送请求
global $_FM;
global $_HI;
//数据取出方法
$dataGet = $_FM['get']; //GET进来的参数
$dataPost = $_FM['post']; //POST进来的参数
$params = Yii::$app->params;
require dirname(__FILE__) . '/_public/plat.php';
$group_pre = 'VCMS-IMMS';
/*设置REDIS缓存*/
//初始化$cache = new \Redis();
$cache = new \Redis();
$cache->connect($params['redis']['IP'], $params['redis']['PORT']);
// 先检查是否存在,然后写入并设置有效时间
$key = 'FmWebSorcketCount';
$CACHE_PREFIX = 'DACMS';
$count = 0;
if ($cache->exists($CACHE_PREFIX . $key)) {
// 读取
$count = $cache->get($CACHE_PREFIX . $key);
//清除
$cache->delete($CACHE_PREFIX . $key);
}
$cache->set($CACHE_PREFIX . $key, $count + 1);
$expire = time() + 604800; //一周时间再过期
$cache->expire($CACHE_PREFIX . $key, $expire);
//前台已经建立起长链接,取得了客户端ID号;需要绑定到当前用户,并返回用户uid,供服务侧同步绑定校验
$viaDomain = fmFunc_server_via_domain(); //来路域名
$viaIP = fmFunc_server_via_ip(); //来路IP
$timestamp = isset($_FM['timestamp']) ? $_FM['timestamp'] : time();
//通过前端GET传入的
$client_id = isset($dataGet['client_id']) ? $dataGet['client_id'] : ' ';
if (!$client_id) {
return;
}
$accessToken = isset($dataGet['accesstoken']) ? $dataGet['accesstoken'] : '';
if (!$accessToken) {
//构造反馈消息
$data = array();
$data['type'] = 'log';
$data['msg'] = '未指定accessToken';
$data = json_encode($data);
//发送给指定客户端
Gateway::sendToClient($client_id, $data);
return;
}
//判断accesstoken有效性
/*
@有效性规则判断
*Yii::$app->user->identity->username,Yii::$app->user->identity->id 当前用户账号及id
*domain 域名匹配
*expiretime 有效期判断
*$_FM['apiCert'] 服务器证书
*/
$connection = yii::$app->db;
$sql = "SELECT `username` FROM c_access WHERE accesstoken = :accesstoken ORDER BY id ASC";
$params = array();
$params[':accesstoken'] = $accessToken;
// $params[':domain'] = $viaDomain;
// $params[':expiretime'] = $timestamp;
$result = fmFunc_pdo_yii_fetch($connection, $sql, $params);
$hasToken = FALSE;
$hasCert = FALSE;
if ($result) {
$username = $result['username'];
$hasToken = TRUE;
//加载证书文件,但无用户登陆状态
$cert = $username . '.php';
if (file_exists($_HI['apiCertPath'] . $cert)) {
$_FM['apiCert'] = array_merge(include($_HI['apiCertPath'] . $cert));
$hasCert = TRUE;
}
} else {
//构造反馈消息
$data = array();
$data['type'] = 'log';
$data['msg'] = '无效的accessToken';
$data = json_encode($data);
//发送给指定客户端
Gateway::sendToClient($client_id, $data);
return;
}
$_FM['apiCert']['token'] = $accessToken;
//处理POST数据
$msg_type = isset($dataPost['msg_type']) ? $dataPost['msg_type'] : '';
if (!$msg_type) {
$msg_type = isset($dataGet['msg_type']) ? $dataGet['msg_type'] : '';
}
$msg = isset($dataPost['msg']) ? $dataPost['msg'] : '';
if (!$msg) {
$msg = isset($dataGet['msg']) ? $dataGet['msg'] : '';
}
//设定群发群组
$group_id = $group_pre . fmFunc_server_hash_id(0);
//构造反馈消息
$data = array();
$data['type'] = $msg_type;
// $data['type'] = 'alert';
$data['msg'] = $msg;
if (isset($dataGet['debug'])) {
//向全体推送数据
$data['msg'] = empty($data['msg']) ? '第' . $count . '次测试群发' : $data['msg'];
$count++;
$data = json_encode($data);
Gateway::sendToGroup($group_id, $data);
return;
}
$data = json_encode($data);
//向全体推送数据
$count++;
Gateway::sendToGroup($group_id, $data);
//构造反馈消息
$data = array();
$data['type'] = 'toast';
$data['msg'] = '消息已发送';
$data = json_encode($data);
//发送给指定客户端
Gateway::sendToClient($client_id, $data);
return;
}
}