You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

637 lines
25 KiB

3 years ago
<?php
namespace apps\wechat\controllers;
use apps\base\controllers\FrontendController;
class IndexController extends FrontendController {
private $weObj = '';
private $orgid = '';
private $wechat_id = '';
/**
* 构造函数
*/
public function __construct()
{
parent::__construct();
// 获取公众号配置
$this->orgid = I('get.orgid');
if (! empty($this->orgid)) {
$file = array('passport');
$this->load_helper($file);
$wxinfo = $this->get_config($this->orgid);
$config['token'] = $wxinfo['token'];
$config['appid'] = $wxinfo['appid'];
$config['appsecret'] = $wxinfo['appsecret'];
$config['encodingaeskey'] = $wxinfo['encodingaeskey'];
$this->weObj = new \vendor\Wechat($config);
$this->weObj->valid();
$this->wechat_id = $wxinfo['id'];
}
}
/**
* 执行方法
*/
public function actionIndex()
{
// 事件类型
$type = $this->weObj->getRev()->getRevType();
$wedata = $this->weObj->getRev()->getRevData();
//logResult(var_export($wedata, true));
$keywords = '';
if ($type == \vendor\Wechat::MSGTYPE_TEXT) {
$keywords = $wedata['Content'];
}
elseif ($type == \vendor\Wechat::MSGTYPE_EVENT) {
if ('subscribe' == $wedata['Event']) {
$scene_id = 0;
// 用户扫描带参数二维码(未关注)
if (isset($wedata['Ticket']) && ! empty($wedata['Ticket'])) {
$scene_id = $this->weObj->getRevSceneId();
$flag = true;
// 关注
$this->subscribe($wedata['FromUserName'], $scene_id);
// 关注时回复信息
$this->msg_reply('subscribe');
}
else{
// 关注
$this->subscribe($wedata['FromUserName']);
// 关注时回复信息
$this->msg_reply('subscribe');
exit;
}
}
elseif ('unsubscribe' == $wedata['Event']) {
// 取消关注
$this->unsubscribe($wedata['FromUserName']);
exit();
}
elseif ('MASSSENDJOBFINISH' == $wedata['Event']) {
// 群发结果
$data['status'] = $wedata['Status'];
$data['totalcount'] = $wedata['TotalCount'];
$data['filtercount'] = $wedata['FilterCount'];
$data['sentcount'] = $wedata['SentCount'];
$data['errorcount'] = $wedata['ErrorCount'];
// 更新群发结果
$this->db->table('wechat_mass_history')
->data($data)
->where(array('msg_id'=>$wedata['MsgID']))
->update();
exit();
}
elseif ('CLICK' == $wedata['Event']) {
// 点击菜单
$keywords = $wedata['EventKey'];
}
elseif ('VIEW' == $wedata['Event']) {
$this->redirect($wedata['EventKey']);
}
elseif ('SCAN' == $wedata['Event']) {
$scene_id = $this->weObj->getRevSceneId();
}
elseif('kf_create_session' == $wedata['Event']){
//多客服接入
}
elseif('kf_close_session' == $wedata['Event']){
//多客服关闭
}
elseif('kf_switch_session' == $wedata['Event']){
//多客服转接
}
} else {
$this->msg_reply('msg');
exit();
}
//扫描二维码
if(!empty($scene_id)){
$qrcode_fun = model()->table('wechat_qrcode')->field('function')->where(array('scene_id'=>$scene_id))->one();
//扫码引荐
if(!empty($qrcode_fun) && isset($flag)){
//增加扫描量
$this->db->query("UPDATE {pre}wechat_qrcode SET scan_num = scan_num + 1 WHERE scene_id = $scene_id");
}
$keywords = $qrcode_fun;
}
// 回复
if (! empty($keywords)) {
//记录用户操作信息
$this->record_msg($wedata['FromUserName'], $keywords);
// 多客服
$rs = $this->customer_service($wedata['FromUserName'], $keywords);
if (empty($rs)) {
// 功能插件
$rs1 = $this->get_function($wedata['FromUserName'], $keywords);
if (empty($rs1)) {
// 关键词回复
$rs2 = $this->keywords_reply($keywords);
if (empty($rs2)) {
// 消息自动回复
$this->msg_reply('msg');
}
}
}
}
}
/**
* 关注处理
*
* @param array $info
*/
private function subscribe($openid = '', $scene_id = 0)
{
if(!empty($openid)){
// 用户信息
$info = $this->weObj->getUserInfo($openid);
if (empty($info)) {
$info = array();
}
// 查找用户是否存在
$where['openid'] = $openid;
$rs = $this->db->table('wechat_user')->field('ect_uid, subscribe')->where($where)->find();
// 未关注
if (empty($rs)) {
$ect_uid = 0;
//查看公众号是否绑定
if(isset($info['unionid'])){
$ect_uid = model()->table('wechat_user')->field('ect_uid')->where(array('unionid'=>$info['unionid']))->one();
}
if(empty($ect_uid)){
$info['parent_id'] = $scene_id;
}
else{
$info['ect_uid'] = $ect_uid;
}
// 获取被关注公众号信息
$info['wechat_id'] = $this->wechat_id;
$this->db->table('wechat_user')->data($info)->insert();
}
else {
$this->db->table('wechat_user')->data($info)->where($where)->update();
}
}
}
/**
* 取消关注
*
* @param string $openid
*/
public function unsubscribe($openid = '')
{
// 未关注
$where['openid'] = $openid;
$rs = $this->db->table('wechat_user')->where($where)->count();
// 修改关注状态
if ($rs > 0) {
$data['subscribe'] = 0;
$this->db->table('wechat_user')->data($data)->where($where)->update();
}
}
/**
* 被动关注,消息回复
*
* @param string $type
* @param string $return
*/
private function msg_reply($type, $return = 0)
{
$replyInfo = $this->db->table('wechat_reply')
->field('content, media_id')
->where(array('type'=>$type, 'wechat_id'=>$this->wechat_id))
->find();
if (! empty($replyInfo)) {
if (! empty($replyInfo['media_id'])) {
$replyInfo['media'] = $this->db->table('wechat_media')
->field('title, content, file, type, file_name')
->where(array('id'=>$replyInfo['media_id']))
->find();
if ($replyInfo['media']['type'] == 'news') {
$replyInfo['media']['type'] = 'image';
}
// 上传多媒体文件
$rs = $this->weObj->uploadMedia(array(
'media' => '@' . ROOT_PATH . $replyInfo['media']['file']
), $replyInfo['media']['type']);
// 回复数据重组
if ($rs['type'] == 'image' || $rs['type'] == 'voice') {
$replyData = array(
'ToUserName' => $this->weObj->getRev()->getRevFrom(),
'FromUserName' => $this->weObj->getRev()->getRevTo(),
'CreateTime' => time(),
'MsgType' => $rs['type'],
ucfirst($rs['type']) => array(
'MediaId' => $rs['media_id']
)
);
} elseif ('video' == $rs['type']) {
$replyData = array(
'ToUserName' => $this->weObj->getRev()->getRevFrom(),
'FromUserName' => $this->weObj->getRev()->getRevTo(),
'CreateTime' => time(),
'MsgType' => $rs['type'],
ucfirst($rs['type']) => array(
'MediaId' => $rs['media_id'],
'Title' => $replyInfo['media']['title'],
'Description' => strip_tags($replyInfo['media']['content'])
)
);
}
if($return){
return array('type'=>'media', 'content'=>$replyData);
}
$this->weObj->reply($replyData);
//记录用户操作信息
$this->record_msg($this->weObj->getRev()->getRevTo(), '图文信息', 1);
} else {
require_once(BASE_PATH . 'apps/base/utils/function.php');
// 文本回复
$replyInfo['content'] = html_out($replyInfo['content']);
if($return){
return array('type'=>'text', 'content'=>$replyInfo['content']);
}
$this->weObj->text($replyInfo['content'])->reply();
//记录用户操作信息
$this->record_msg($this->weObj->getRev()->getRevTo(), $replyInfo['content'], 1);
}
}
}
/**
* 关键词回复
*
* @param string $keywords
* @return boolean
*/
private function keywords_reply($keywords)
{
require_once(BASE_PATH . 'apps/base/utils/function.php');
$endrs = false;
$sql = 'SELECT r.content, r.media_id, r.reply_type FROM {pre}wechat_reply r LEFT JOIN {pre}wechat_rule_keywords k ON r.id = k.rid WHERE k.rule_keywords = "' . $keywords . '" and r.wechat_id = ' . $this->wechat_id . ' order by r.add_time desc LIMIT 1';
$result = $this->db->query($sql);
if (! empty($result)) {
// 素材回复
if (! empty($result[0]['media_id'])) {
$mediaInfo = $this->db->table('wechat_media')
->field('id, title, digest, content, file, type, file_name, article_id, link')
->where(array('id'=>$result[0]['media_id']))
->find();
// 回复数据重组
if ($result[0]['reply_type'] == 'image' || $result[0]['reply_type'] == 'voice') {
// 上传多媒体文件
$rs = $this->weObj->uploadMedia(array(
'media' => '@' . ROOT_PATH . $mediaInfo['file']
), $result[0]['reply_type']);
$replyData = array(
'ToUserName' => $this->weObj->getRev()->getRevFrom(),
'FromUserName' => $this->weObj->getRev()->getRevTo(),
'CreateTime' => time(),
'MsgType' => $rs['type'],
ucfirst($rs['type']) => array(
'MediaId' => $rs['media_id']
)
);
// 回复
$this->weObj->reply($replyData);
$endrs = true;
} elseif ('video' == $result[0]['reply_type']) {
// 上传多媒体文件
$rs = $this->weObj->uploadMedia(array(
'media' => '@' . ROOT_PATH . $mediaInfo['file']
), $result[0]['reply_type']);
$replyData = array(
'ToUserName' => $this->weObj->getRev()->getRevFrom(),
'FromUserName' => $this->weObj->getRev()->getRevTo(),
'CreateTime' => time(),
'MsgType' => $rs['type'],
ucfirst($rs['type']) => array(
'MediaId' => $rs['media_id'],
'Title' => $replyInfo['media']['title'],
'Description' => strip_tags($replyInfo['media']['content'])
)
);
// 回复
$this->weObj->reply($replyData);
$endrs = true;
} elseif ('news' == $result[0]['reply_type']) {
// 图文素材
$articles = array();
if (! empty($mediaInfo['article_id'])) {
$artids = explode(',', $mediaInfo['article_id']);
foreach ($artids as $key => $val) {
$artinfo = $this->db->table('wechat_media')
->field('id, title, file, digest, content, link')
->where(array('id'=>$val))
->find();
$artinfo['content'] = sub_str(strip_tags(html_out($artinfo['content'])), 100);
$articles[$key]['Title'] = $artinfo['title'];
$articles[$key]['Description'] = empty($artinfo['digest']) ? $artinfo['content'] : $artinfo['digest'];
$articles[$key]['PicUrl'] = __URL__ . '/' . $artinfo['file'];
$articles[$key]['Url'] = empty($artinfo['link']) ? U('article/index/wechat_news_info', array('id'=>$artinfo['id']), true) : $artinfo['link'];
}
} else {
$articles[0]['Title'] = $mediaInfo['title'];
$articles[0]['Description'] = empty($mediaInfo['digest']) ? sub_str(strip_tags(html_out($mediaInfo['content'])), 100) : $mediaInfo['content'];
$articles[0]['PicUrl'] = __URL__ . '/' . $mediaInfo['file'];
$articles[0]['Url'] = empty($mediaInfo['link']) ? U('article/index/wechat_news_info', array('id'=>$mediaInfo['id']), true) : $mediaInfo['link'];
}
// 回复
$this->weObj->news($articles)->reply();
//记录用户操作信息
$this->record_msg($this->weObj->getRev()->getRevTo(), '图文信息', 1);
$endrs = true;
}
} else {
// 文本回复
$result[0]['content'] = html_out($result[0]['content']);
$this->weObj->text($result[0]['content'])->reply();
//记录用户操作信息
$this->record_msg($this->weObj->getRev()->getRevTo(), $result[0]['content'], 1);
$endrs = true;
}
}
return $endrs;
}
/**
* 功能变量查询
*
* @param unknown $tousername
* @param unknown $fromusername
* @param unknown $keywords
* @return boolean
*/
public function get_function($fromusername, $keywords)
{
$return = false;
$rs = $this->db->query("SELECT name, keywords, command, config FROM {pre}wechat_extend WHERE keywords like '%$keywords%' and enable = 1 and wechat_id = $this->wechat_id ORDER BY id ASC");
/*if($rs){
$key = explode(',', $rs['keywords']);
if(!in_array($keywords, $key)){
return $return;
}
}*/
$file = ADDONS_PATH . 'wechat/' . $rs[0]['command'] . '/' . $rs[0]['command'] . '.class.php';
if (file_exists($file)) {
require_once ($file);
$wechat = new $rs[0]['command']();
$data = $wechat->show($fromusername, $rs[0]);
if (! empty($data)) {
// 数据回复类型
if ($data['type'] == 'text') {
$this->weObj->text($data['content'])->reply();
//记录用户操作信息
$this->record_msg($fromusername, $data['content'], 1);
} elseif ($data['type'] == 'news') {
$this->weObj->news($data['content'])->reply();
//记录用户操作信息
$this->record_msg($fromusername, '图文消息', 1);
}
$return = true;
}
}
return $return;
}
/**
* 模板消息提醒
* @return boolean
*/
static function template_message($openid ='', $template_id = '', $data = array(), $url = '')
{
$config = model()->table('wechat')
->field('token, appid, appsecret')
->where(array('id'=>1, 'status'=>1))
->find();
if(empty($config)){
return array('code'=>1, 'msg'=>'请先配置好公众号');
}
if(empty($openid) || empty($template_id)){
return array('code'=>1, 'msg'=>'缺少发送对象或消息模板');
}
$template = model()->table('wechat_template')->where(array('template_id'=>$template_id, 'status'=>1, 'wechat_id'=>1))->count();
if(empty($template)){
return array('code'=>1, 'msg'=>'消息模板不可用或不存在');
}
$weObj = new \vendor\Wechat($config);
$template_data = array(
"touser" => $openid,
"template_id" => $template_id,
"url" => $url,
"topcolor" => "#FF0000",
"data" => $data
);
$rs = $weObj->sendTemplateMessage($template_data);
if(empty($rs)){
return array('code'=>1, 'msg'=>$weObj->errMsg);
}
return array('code'=>0);
}
/**
* 多客服
*
* @param unknown $fromusername
* @param unknown $keywords
*/
public function customer_service($fromusername, $keywords)
{
$result = false;
// 是否处在多客服流程
$kfsession = $this->weObj->getKFSession($fromusername);
if(empty($kfsession) || empty($kfsession['kf_account'])){
$kefu = model()->table('wechat_user')->field('openid')->where(array('openid'=>$fromusername))->one();
if($kefu && $keywords == 'kefu'){
$rs = $this->db->table('wechat_extend')->field('config')->where(array('command'=>'kefu', 'enable'=>1, 'wechat_id'=>$this->wechat_id))->one();
if (! empty($rs)) {
$config = unserialize($rs);
$msg = array(
'touser' => $fromusername,
'msgtype' => 'text',
'text' => array(
'content' => '欢迎进入多客服系统'
)
);
$this->weObj->sendCustomMessage($msg);
//记录用户操作信息
$this->record_msg($fromusername, $msg['text']['content'], 1);
// 在线客服列表
$online_list = $this->weObj->getCustomServiceOnlineKFlist();
if ($online_list['kf_online_list']) {
foreach ($online_list['kf_online_list'] as $key => $val) {
if ($config['customer'] == $val['kf_account'] && $val['status'] > 0 && $val['accepted_case'] < $val['auto_accept']) {
$customer = $config['customer'];
} else {
$customer = '';
}
}
}
// 转发客服消息
$this->weObj->transfer_customer_service($customer)->reply();
$result = true;
}
}
}
return $result;
}
/**
* 关闭多客服菜单
*/
public function close_kf($openid, $keywords){
$openid = $this->model->table('wechat_user')->field('openid')->where(array('openid'=>$openid))->one();
if($openid){
$kfsession = $this->weObj->getKFSession($openid);
if($keywords == 'q' && isset($kfsession['kf_account']) && !empty($kfsession['kf_account'])){
$rs = $this->weObj->closeKFSession($openid, $kfsession['kf_account'], '客户已主动关闭多客服');
if($rs){
$msg = array(
'touser' => $openid,
'msgtype' => 'text',
'text' => array(
'content' => '您已退出多客服系统'
)
);
$this->weObj->sendCustomMessage($msg);
return true;
}
}
}
return false;
}
/**
* 记录用户操作信息
*/
public function record_msg($fromusername, $keywords, $iswechat = 0){
$uid = model()->table('wechat_user')->field('uid')->where(array('openid'=>$fromusername))->one();
if($uid){
$data['uid'] = $uid;
$data['msg'] = $keywords;
$data['send_time'] = time();
//是公众号回复
if($iswechat){
$data['iswechat'] = 1;
}
$this->db->table('wechat_custom_message')
->data($data)
->insert();
}
}
/**
* 检查是否是微信浏览器访问
*/
static function is_wechat_browser()
{
$user_agent = $_SERVER['HTTP_USER_AGENT'];
if (strpos($user_agent, 'MicroMessenger') === false) {
return false;
} else {
return true;
}
}
/**
* 插件页面显示方法
*
* @param string $plugin
*/
public function actionPluginShow()
{
if(self::is_wechat_browser() && ((!isset($_SESSION['openid']) || empty($_SESSION['openid'])) || empty($_SESSION['user_id']))){
$redirect_url = __HOST__ . $_SERVER['REQUEST_URI'];
$this->redirect(U('oauth/index/index', array('type'=>'wechat', 'back_url'=>$redirect_url)));
}
$plugin = I('get.name');
$file = ADDONS_PATH . 'wechat/' . $plugin . '/' . $plugin . '.class.php';
if (file_exists($file)) {
include_once ($file);
$wechat = new $plugin();
$wechat->html_show();
}
}
/**
* 插件处理方法
*
* @param string $plugin
*/
public function actionPluginAction()
{
$plugin = I('get.name');
$file = ADDONS_PATH . 'wechat/' . $plugin . '/' . $plugin . '.class.php';
if (file_exists($file)) {
include_once ($file);
$wechat = new $plugin();
$wechat->action();
}
}
/**
* 获取公众号配置
*
* @param string $orgid
* @return array
*/
private function get_config($orgid)
{
$config = model()->table('wechat')
->field('id, token, appid, appsecret, encodingaeskey')
->where(array('orgid'=>$orgid, 'status'=>1))
->find();
if (empty($config)) {
$config = array();
}
return $config;
}
/**
* 获取access_token的接口
* @return [type] [description]
*/
public function check_auth(){
$appid = I('get.appid');
$appsecret = I('get.appsecret');
if(empty($appid) || empty($appsecret)){
echo json_encode(array('errmsg'=>'信息不完整,请提供完整信息', 'errcode'=>1));
exit;
}
$config = $this->model->table('wechat')
->field('token, appid, appsecret')
->where(array('appid'=>$appid, 'appsecret'=>$appsecret, 'status'=>1))
->find();
if(empty($config)){
echo json_encode(array('errmsg'=>'信息错误,请检查提供的信息', 'errcode'=>1));
exit;
}
$obj = new \verdor\Wechat($config);
$access_token = $obj->checkAuth();
if($access_token){
echo json_encode(array('access_token'=>$access_token, 'errcode'=>0));
exit;
}
else{
echo json_encode(array('errmsg'=>$obj->errmsg, 'errcode'=>$obj->errcode));
exit;
}
}
}