tplmsg 发送模板消息的类
<?php namespace app\admin\controller; use app\admin\controller\Base; use think\Cache; //include_once(dirname(__FILE__).'/Swclient.php'); class Tplmsg extends Base { protected $wxObj; protected $keySize; public function __construct() { parent::__construct(); $this->keySize = 1000; } public function lst() { // $list = ArticleModel::paginate(3); //$list = BannerModel::paginate(3); if(session('uid')==2){ $list=db('tplmsg')->alias('a')->join('wxaccount c','c.id=a.msg_id')->field('a.msg_id,a.title,a.template_id,c.appid,c.name')->paginate(20); //print_r($list);exit; // $list=db('Tplmsg')->paginate(10); }else{ $list=db('tplmsg')->alias('a')->join('wxaccount c','c.id=a.msg_id')->field('a.msg_id,a.title,a.template_id,c.appid,c.name')->where(array("a.uid"=>session('uid')))->paginate(3); } //$list = BannerModel::paginate(3)->group("sort"); $this->assign('list',$list); return $this->fetch(); } // //暂时理解成都用外链 // public function add() // { // if(request()->isPost()){ // // dump($_FILES); // // dump($_POST); die; // $data=[ // 'title'=>input('title'), // 'content'=>input('content'), // 'time'=>time(), // 'img_url'=>input('img_url'), // 'jump_url'=>input('jump_url'), // 'uid'=>session('uid') // ]; // $validate = \think\Loader::validate('kefu'); // if(!$validate->scene('add')->check($data)){ // $this->error($validate->getError()); die; // } // // if($_FILES['pic']['tmp_name']){ // // $file = request()->file('pic'); // // //exit('41'); // // $info = $file->move(ROOT_PATH . 'public' . DS . 'static/uploads'); // // $data['pic']='/static/uploads/'.$info->getSaveName(); // // $file_path = str_replace('\\','/',"/public/".$data['pic']); // // //D:/web/PHPTutorial/WWW/tp5//public//static/uploads/20180426/204b67841cfeb0d80ae1b000f6cfb8c5.jpg // // // // // $big_file_path = str_replace('.','_small.',$file_path); // // $image = \think\Image::open(ROOT_PATH.$file_path); // // // 按照原图的比例生成一个最大为150*150的缩略图并保存为thumb.png // // $image->thumb(350, 350)->save(ROOT_PATH.$big_file_path); // // } // if(db('kefu')->insert($data)){ // return $this->success('添加客服消息成功!','lst'); // }else{ // return $this->error('添加客服消息失败!'); // } // return; // } // // $cateres=db('cate')->select(); // // $this->assign('cateres',$cateres); // return $this->fetch(); // } /* public function add() { if(request()->isPost()){ dump($_FILES); dump($_POST); die; $data=[ 'title'=>input('title'), 'author'=>input('author'), 'desc'=>input('desc'), 'keywords'=>str_replace(',', ',', input('keywords')), 'content'=>input('content'), 'cateid'=>input('cateid'), 'time'=>time(), ]; if(input('state')=='on'){ $data['state']=1; } if($_FILES['pic']['tmp_name']){ $file = request()->file('pic'); $info = $file->move(ROOT_PATH . 'public' . DS . 'static/uploads'); $data['pic']='/uploads/'.$info->getSaveName(); } $validate = \think\Loader::validate('Article'); if(!$validate->scene('add')->check($data)){ $this->error($validate->getError()); die; } if(db('Article')->insert($data)){ return $this->success('添加文章成功!','lst'); }else{ return $this->error('添加文章失败!'); } return; } $cateres=db('cate')->select(); $this->assign('cateres',$cateres); return $this->fetch(); } */ // public function edit(){ // $id=input('id'); // $banner=db('kefu')->find($id); // if(request()->isPost()){ // $data=[ // 'kid'=>input('id'), // 'title'=>input('title'), // 'content'=>input('content'), // 'time'=>time(), // 'img_url'=>input('img_url'), // 'jump_url'=>input('jump_url'), // 'uid'=>session('uid') // ]; // $validate = \think\Loader::validate('kefu'); // if(!$validate->scene('edit')->check($data)){ // $this->error($validate->getError()); die; // } // if(db('kefu')->update($data)){ // $this->success('修改客服消息成功!','lst'); // }else{ // $this->error('修改客服消息失败!'); // } // return; // } // $this->assign('banner',$banner); // // $cateres=db('cate')->select(); // // $this->assign('cateres',$cateres); // return $this->fetch(); // } // public function del(){ // $id=input('kid'); // if(db('kefu')->delete(input('kid'))){ // Cache::rm('banners'); // $this->success('删除客服消息成功!','lst'); // }else{ // $this->error('删除客服消息失败!'); // } // } public function send(){ // $client=new Swclient(); //include_once( dirname(__FILE__).'/sw_client.php'); if(request()->isPost()){ //print_r($_POST);exit; // //因为不确定字段只能for循环一下 // foreach($_POST as $d =>$f){ // if($d=="openid"){ // continue; // } // if(strlen($f)==0){ // $this->error('字段不能为空'); // } // } //再验证一下url // // // if(!$this->validateURL($_POST['url'])){ // $this->error('url地址不正确'); // } // print_r($_POST);exit; /* Array ( [title] => 预约成功通知 [url] => 123 [img_url] => xxxxxxxxxxxxxxxxxx [first] => 111 [color_first] => #80ff00 [keyword1] => 222 [color_keyword1] => #ff80ff [keyword2] => 333 [color_keyword2] => #ffff80 [remark] => 444 [color_remark] => #0000ff [openid] => 555 ) */ $_id = input('id'); $mid = input('mid'); if ($_id == 0) { $this->error('非法操作!'); } $tplMsgArr = db('tplmsg')->where(array("template_id"=>$mid))->find(); //$tplMsgArr = db('tplmsg')->where(array("msg_id"=>$_id))->find(); $mpArr = db('wxaccount')->where(array("id"=>$tplMsgArr['msg_id']))->find(); $tplKeyArr = $this->formatTplKey($tplMsgArr['content']); $this->wxObj = new Weixin($mpArr['appid'], $mpArr['appsecret']); $data = array( 'template_id' => $tplMsgArr['template_id'], 'url' => input('post.url') ); foreach ($tplKeyArr as $k => $v) { $data['data'][$v] = array( 'value' => input('post.' . $v), 'color' => input('post.color_' . $v), ); } file_put_contents('ss.txt',json_encode($data)); $redis = new \Redis; $redis->connect('127.0.0.1', 6379); $openid = input('post.openid'); if (!empty($openid)) { $data['touser'] = $openid; //print_r($data); $res = $this->wxObj->sendTplMsg($data); // print_r($res);exit(); if ($res['errcode'] == 0 && $res['errmsg'] == 'ok') { $ajax_data['msg']="发送成功"; $ajax_data['status'] = "1"; exit(json_encode($ajax_data)); // echo "<script>alert('发送成功');location.reload();</script>"; //$this->url_redirect('模板消息测试发送成功!', '', '继续发送模板消息'); } else { $ajax_data['msg']="发送失败"; $ajax_data['status'] = "0"; exit(json_encode($ajax_data)); //$this->url_redirect('模板消息测试发送失败!错误代码:' . $res['errcode'], '', '继续发送模板消息'); } }else{ // $data['wxurl'] ='https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$this->wxObj->getAccessToken(); //这里试下swoole // $data['touser'] = "xxxxxxxxxx"; // $params['data']=$data;//接口数据 // $params['wxurl'] = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$this->wxObj->getAccessToken(); // $msg = json_encode($params); // $client = new sw_client(); /* $client = new \swoole_client(SWOOLE_SOCK_TCP); for($i=0;$i<10000;$i++) { if (!$client->connect('127.0.0.1', 9501,1)) { $this->write("connect failed."); } //向服务器发送数据 if (!$client->send($msg)) { $this->write("send ".$msg." failed."); } //关闭连接 $client->close(); //$client->send($msg); //echo "[".date("Y-m-d H:i:s")."]执行完成".PHP_EOL; } */ Cache::set('sendSucc_tpl_' . $_id, 0, 3600 * 24); Cache::set('sendFail_tpl_' . $_id, 0, 3600 * 24); $message = serialize(array('msg_id' => $_id, 'mp_id' => $tplMsgArr['msg_id'], 'fans' => $mpArr['num'], 'msg_title' => $tplMsgArr['title'])); $logId=db('log')->insertGetId(array('type' => 'tpl_msg','fans'=>$mpArr['num'],'name'=>$mpArr['name'],'message' => $message, 'arg1' => 0, 'arg2' => 0,'time'=>time())); $news=array(); $current = 0; $sb=0; $params['wxurl'] = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$this->wxObj->getAccessToken(); //echo $params['wxurl'];exit; //关闭连接 // $client = new \swoole_client(SWOOLE_SOCK_TCP); // // $client = new \swoole_client(SWOOLE_SOCK_TCP,SWOOLE_SOCK_SYNC); while ($openidArr = Cache::get('openidList_' . $tplMsgArr['msg_id'] . '_' . $current)) { $curKey = 0; // while ($subOpenidArr = array_slice($openidArr, $curKey, 5)) { // // print_r($subOpenidArr); // $params['ids'] = $subOpenidArr; // $params['data']=$data;//接口数据 // //$msg = json_encode($params); // // $client = new sw_client(); // // $msg = $params; // $curKey += 5; // $news[] = $params; // $ks = "key_".$sb; // $sb++; // $redis->set($ks,json_encode($news)); // } // file_put_contents('88.txt',count($openidArr), FILE_APPEND); while ($subOpenidArr = array_slice($openidArr, $curKey, 50)) { //print_r($subOpenidArr);exit; //$params['ids'] = $subOpenidArr; //ids 循环给touser //$msg = json_encode($params); //$client = new sw_client(); $params['tpl_id'] = $_id; $params['mp_id'] = $tplMsgArr['msg_id']; $params['log_id'] = $logId; //$data['touser'] = "oq05X0SgNIuJGG_3ByDRKFTVxtNA"; $params['ids'] = $subOpenidArr; $params['data']=$data;//接口数据 $msg = $params; // $sb += count($params['ids']); // for($i=0;$i<200;$i++){ //$client = new \swoole_client(SWOOLE_SOCK_TCP,SWOOLE_SOCK_SYNC); // if (!$client->connect('127.0.0.1', 9501,1)) // { // $this->write("connect failed."); // } // for($i=0;$i<6000;$i++){ // for($i=0;$i<5;$i++){ // $client->send($msg); // } // $redis->lpush('lb', 'value') $news[] = $msg; // $redis->set("sb","dsb"); // $redis->incr("key"); // echo "[".date("Y-m-d H:i:s")."]执行完成".PHP_EOL; //向服务器发送数据 //if (!$client->send($msg)) // { // file_put_contents('shibaicishu.txt',"i".PHP_EOL, FILE_APPEND); // $this->write("send ".$msg." failed."); // } // file_put_contents('cishu.txt',"1".PHP_EOL, FILE_APPEND); // $news[]=$subOpenidArr; // } // print_r($news);exit; // file_put_contents('99.txt',serialize($openidArr).PHP_EOL, FILE_APPEND); $curKey += 50; } //file_put_contents('99.txt',$subOpenidArr.PHP_EOL, FILE_APPEND); //\Lib\GearmanClient::add_job('sendTplMsg', serialize($dataArr)); // print_r(unserialize($msg)); // exit; // } $current += $this->keySize; $ks = "key_".$sb; $sb++; //这里应该是有50一组的 *20个 $redis->set($ks,json_encode($news)); //print_r($news);exit; $news = array(); exec("php /www/wwwroot/www.xxxxx.cn/application/admin/controller/Swclient.php {$ks}"); //} // echo $redis->get($ks); // exit("3"); //$current += $this->keySize; } //重定向到News模块的Category操作 $this->redirect('sendspeed/lst', ['id' => $logId]); //file_put_contents("nums.txt",$sb); // print_r($news); } }else{ $_id = input('id'); $mid = input('mid'); if ($_id == 0) { $this->error('非法操作!'); } $tplMsgArr = db('tplmsg')->where(array("template_id"=>$mid))->find(); //print_r($tplMsgArr); /* Array ( [title] => 预约成功通知 [primary_industry] => IT科技 [deputy_industry] => 互联网|电子商务 [content] => {{first.DATA}} 时间:{{keyword1.DATA}} [example] => 您好,您在友推友预约的商品经成功了 时间:2017年7月13日 链接:https://mp.weixin.qq.com/advanced/tmplmsg?action=open_edit&token=402070777&lang=zh_CN 友推友感谢您的使用 [uid] => 2 [time] => 1526277978 ) */ $tplKeyArr = $this->formatTplKey($tplMsgArr['content']); //print_r($tplKeyArr);exit; /* Array ( [0] => first [1] => keyword1 [2] => keyword2 [3] => remark ) */ /* {foreach from=$tplKeyArr item=tItem} <div class="form-group" style="margin-bottom:0;"> <label for="{$tItem}" class=" col-sm-3 control-label">{$tItem}:</label> <div class="col-sm-5"> </div> </div> <div class="form-group"> <label for="color_{$tItem}" class=" col-sm-3 control-label">字体颜色:</label> <div class="col-sm-5"> </div> </div> {/foreach} */ $this->assign('tplKeyArr',$tplKeyArr); $this->assign('tplMsgArr',$tplMsgArr); $content = str_replace(array("\r\n", "\r", "\n"), '<br />', $tplMsgArr['content']); $content = preg_replace('/\{\{(.+?)\.DATA\}\}/', '<span class="\\1 color_\\1">{{\\1}}</span>', $content); $this->assign('content',$content); $this->assign('_id', $_id); return $this->fetch(); } } // 格式化模板消息参数Key public function formatTplKey($content = '') { $keyArr = array(); if (preg_match_all('/\{\{(.+?)\}\}/', $content, $matchs)) { foreach ($matchs[1] as $k => $v) { $keyArr[] = substr($v, 0, strpos($v, '.')); } } return $keyArr; } private function write($str){ $path = "/sys.log"; $str = "[".date("Y-m-d H:i:s")."]".$str; $str .= PHP_EOL; file_put_contents($path,$str,FILE_APPEND); } public function validateURL($URL) { $pattern_1 = "/^(http|https):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i"; $pattern_2 = "/^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i"; if(preg_match($pattern_1, $URL) || preg_match($pattern_2, $URL)){ return true; } else{ return false; } } }
Weixin.php
<?php namespace app\admin\controller; use app\admin\model\Wxaccount as WxaccountModel; use app\admin\controller\Base; use think\Cache; class Weixin { protected $appid; protected $appsecret; protected $tokenFile; //token缓存文件 protected $ticketFile; //ticket缓存文件 protected $expires; protected $access_token; protected $tokenCacheKey; protected $ticketCacheKey; public function __construct($appid = NULL, $appsecret = NULL) { if ($appid && $appsecret) { $this->appid = $appid; $this->appsecret = $appsecret; } else { echo "appid或appsecret为空"; return; } $this->tokenCacheKey = $appid . '_access_token'; $this->ticketCacheKey = $appid . '_js_api_ticket'; $this->expires = 5000; $this->access_token = $this->getAccessToken(); } // 接口验证 public function valid($token = '') { $echoStr = input('get.echostr'); if (empty($echoStr)) return TRUE; if ($this->checkSignature($token)) { ob_end_clean(); die($echoStr); } return FALSE; } // 验证签名 private function checkSignature($token = 'test') { if (empty($token)) $token = 'test'; $signature = input('get.signature'); $timestamp = input('get.timestamp'); $nonce = input('get.nonce'); $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr, SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); ob_start(); var_dump(input('get.echostr'), $signature, $token, $timestamp, $nonce, $tmpStr); $res = ob_get_clean(); file_put_contents('/tmp/weixin.log', $res . PHP_EOL, FILE_APPEND); if ($tmpStr == $signature) { return true; } else { return false; } } /** * 获取access_token */ public function getAccessToken($is_flush = false) { Cache::rm($this->tokenCacheKey); $this->access_token = Cache::get($this->tokenCacheKey); if (empty($this->access_token) || $is_flush) { $this->access_token = $this->getToken(); Cache::set($this->tokenCacheKey, $this->access_token, $this->expires); Cache::set($this->ticketCacheKey, NULL); } return $this->access_token; } /** * 实时获取access_token */ private function getToken() { $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->appid . "&secret=" . $this->appsecret; //echo $url;exit; $tmpInfo = $this->httpGet($url); $info = json_decode($tmpInfo, true); // print_r($info);exit; if ($info['access_token'] != '') { return $info['access_token']; } } /** * 获取Signature签名 */ public function getSignature($timestamp = '1499992323') { $jsapiTicket = $this->getJsApiTicket(); $url = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . ""; $nonceStr = $timestamp; // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; $signature = sha1($string); return $signature; } /** * 获取jsapi_ticket */ public function getJsApiTicket($is_flush = false) { // jsapi_ticket 应该全局存储与更新,以下代码以写入到memcache中做示例 $jsapiticket = S($this->ticketCacheKey); if (empty($jsapiticket) || $is_flush) { $jsapiticket = $this->getTicket(); S($this->ticketCacheKey, $jsapiticket, $this->expires); } return $jsapiticket; } /** * 获取实时jsapi_ticket */ public function getTicket() { $accessToken = $this->getAccessToken(); $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" . $this->getAccessToken(); $res = json_decode($this->httpGet($url)); $jsapi_ticket = $res->ticket; if ($jsapi_ticket) return $jsapi_ticket; return false; } public function createNoncestr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } public function getOpenidList($next_openid = '') { $accessToken = $this->getAccessToken(); $url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token=' . $accessToken . '&next_openid=' . $next_openid; $ret_json = $this->httpGet($url); $ret = json_decode($ret_json, TRUE); return $ret; } public function getTemplate() { $accessToken = $this->getAccessToken(); $url = 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=' . $accessToken; $ret_json = $this->httpGet($url); $ret = json_decode($ret_json, TRUE); return $ret; } public function sendTplMsg($data = array()) { $accessToken = $this->getAccessToken(); $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $accessToken; $ret_json = $this->httpPost($url, json_encode($data)); $ret = json_decode($ret_json, TRUE); // if ($ret['errcode'] == '40001') { // $accessToken = $this->getAccessToken(true); // $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=' . $accessToken; // $ret_json = $this->httpPost($url, json_encode($data)); // $ret = json_decode($ret_json, TRUE); // } return $ret; } // 发送客服消息 public function send_kfmsg($dataArr = array()) { if (!empty($dataArr)) { $accessToken = $this->getAccessToken(); $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $accessToken; $postStr = preg_replace_callback('/\\\\u([0-9a-f]{4})/i', create_function( '$matches', 'return mb_convert_encoding(pack("H*", $matches[1]), "UTF-8", "UCS-2BE");' ), json_encode($dataArr)); $ret_json = $this->httpPost($url, $postStr); $ret = json_decode($ret_json, true); // if ($ret['errcode'] == '40001') { // $accessToken = $this->getAccessToken(true); // $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $accessToken; // $ret_json = $this->httpPost($url, $postStr); // $ret = json_decode($ret_json, true); // } return $ret; } } //上传图片 public function upload_image($file = '', $file_info = array()) { $url = 'https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=' . $this->getAccessToken() . '&type=image'; $res = $this->httpPost($url, array('media' => new \CURLFile($file), 'form-data' => $file_info)); $ret = json_decode($res, true); return $ret; } protected function httpGet($url, $data = null, $time = 10) { $ch = curl_init(); curl_setopt($ch, CURLOPT_TIMEOUT, $time); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $tmpInfo = curl_exec($ch); if (curl_errno($ch)) { return curl_error($ch); } curl_close($ch); return $tmpInfo; } protected function httpPost($url, $data = null, $time = 10) { $ch = curl_init(); //curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); curl_setopt($ch, CURLOPT_TIMEOUT, $time); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $temp = curl_exec($ch); if (curl_errno($ch)) { return curl_error($ch); } curl_close($ch); return $temp; } }
wxaccount.php
<?php namespace app\admin\controller; use app\admin\model\Wxaccount as WxaccountModel; use app\admin\controller\Base; use think\Cache; class Wxaccount extends Base { protected $wxObj; protected $keySize; public function __construct() { parent::__construct(); $this->keySize = 1000; } public function lst() { // $list = ArticleModel::paginate(3); // $list=db('article')->alias('a')->join('cate c','c.id=a.cateid')->field('a.id,a.title,a.pic,a.author,a.state,c.catename')->paginate(3); // 2是超级管理员 if(session('uid')==2){ //$list=db('wxaccount')->where(array('uid'=>session('uid')))->paginate(10); $list = WxaccountModel::paginate(10); } else{ $list=db('wxaccount')->where(array('uid'=>session('uid')))->paginate(10); } // // foreach ($list as $key => $value) { // $list[$key]['state'] = 0; // } $this->assign('list',$list); return $this->fetch(); } public function add() { if(request()->isPost()){ $data=[ 'appid'=>input('appid'), 'appsecret'=>input('appsecret'), 'name'=>input('name'), 'num'=>input('num'), 'time'=>time(), 'uid'=>session('uid'), ]; $validate = \think\Loader::validate('Wxaccount'); if(!$validate->scene('add')->check($data)){ $this->error($validate->getError()); die; } if(db('wxaccount')->insert($data)){ // Cache::rm('wxaccount'); return $this->success('添加微信公众号成功!','lst'); }else{ return $this->error('添加微信公众号!'); } return; } return $this->fetch(); } public function edit(){ $id=input('id'); $articles=db('Wxaccount')->find($id); if(request()->isPost()){ $data=[ 'id'=>input('id'), 'appid'=>input('appid'), 'appsecret'=>input('appsecret'), 'name'=>input('name'), 'num'=>input('num'), 'time'=>time(), 'uid'=>session('uid'), ]; $validate = \think\Loader::validate('Wxaccount'); if(!$validate->scene('edit')->check($data)){ $this->error($validate->getError()); die; } if(db('Wxaccount')->update($data)){ $this->success('修改微信公众号成功!','lst'); }else{ $this->error('修改微信公众号失败!'); } return; } $this->assign('articles',$articles); return $this->fetch(); } public function del(){ $id=input('id'); if(db('Wxaccount')->delete(input('id'))){ $this->success('删除修改微信公众号成功!','lst'); }else{ $this->error('删除修改微信公众号失败!'); } } //获取粉丝的 模仿之前之前那个哥们写的 public function ajaxGetOpenids() { $_id = input('post._id/d'); $mpArr=db('Wxaccount')->where(array("id"=>$_id))->find(); if(empty($mpArr)){ $data['msg'] = "非法请求"; $data['status'] = 0; exit(json_encode($data)); } $this->wxObj = new Weixin($mpArr['appid'], $mpArr['appsecret']); $current = 0; $next_openid = ''; $total = 0; //9_3JM_N1lL2h0aZPM52tVaeL_lB3wAtYbiEddXUZa6Q4eY7A9OSsavROvzPlJMwGQNbW-_9F2D_qdc6On7m5o1Szhb_cl1zPBuUPFp_iLodq_doT6NkS-MImV0fyn_K9ybeBWh4ueEWV2fVF6pEEJfAJAIIN // print_r($this->getOpenidList($_id, $next_openid));exit; while ($openidArr = $this->getOpenidList($_id, $next_openid)) { /* Array ( [total] => 2 [count] => 2 [data] => Array ( [openid] => Array ( [0] => o9SW-jlAsvqneQWkfloZd_wLHi0s [1] => o9SW-jvmfKEuKAJkZpdn6_exjTtA ) ) [next_openid] => o9SW-jvmfKEuKAJkZpdn6_exjTtA ) */ $total = $openidArr['total']; $curKey = 0; while ($subOpenidArr = array_slice($openidArr['data']['openid'], $curKey, $this->keySize)) { Cache::set('openidList_' . $_id . '_' . $current, $subOpenidArr, 3600 * 24 * 7); $current += $this->keySize; $curKey += $this->keySize; } $next_openid = $openidArr['next_openid']; } $mpArr=db('Wxaccount')->where(array("id"=>$_id))->update(array("num"=>$total)); // $this->mpModel->where($where)->data(array('fans' => $total))->save(); // var_dump(S('openidList_' . $_id . '_' . 0));die; // // while (Cache::get('openidList_' . $_id . '_' . $current)) { Cache::set('openidList_' . $_id . '_' . $current, null); $current += $this->keySize; } // while (S('openidList_' . $_id . '_' . $current)) { // S('openidList_' . $_id . '_' . $current, null); // $current += $this->keySize; // } $data['status'] = 1; $data['msg'] = 'ok'; exit(json_encode($data)); //$this->resReturn(0, 'OK!', array('last' => $next_openid)); // } protected function getOpenidList($_id = 0, $next_openid = '') { $openidArr = $this->wxObj->getOpenidList($next_openid); if (!empty($openidArr) && !empty($openidArr['next_openid']) && $openidArr['total'] > 0) { return $openidArr; } return FALSE; } public function ajaxGetTplMsg() { $_id = input('post._id/d'); $mpArr=db('Wxaccount')->where(array("id"=>$_id))->find(); if(empty($mpArr)){ $data['msg'] = "非法请求"; $data['status'] = 0; exit(json_encode($data)); } $this->wxObj = new Weixin($mpArr['appid'], $mpArr['appsecret']); $tplArr = $this->wxObj->getTemplate(); // print_r($tplArr);exit; if (!empty($tplArr['template_list'])) { //$this->tplMsgModel = D('TplMsg'); $data['tpl_list'] = $tplArr['template_list']; db('tplmsg')->where(array('msg_id' => $_id))->delete(); //一般情况下只会发一条 foreach ($tplArr['template_list'] as $k => $v) { $data = array('msg_id' => $_id, 'template_id' => $v['template_id'], 'title' => $v['title'], 'primary_industry' => $v['primary_industry'], 'deputy_industry' => $v['deputy_industry'], 'content' => $v['content'], 'example' => $v['example'], 'uid'=>session('uid'), 'time'=>time(), ); $ok = db('tplmsg')->insert($data); } if($ok){ $data['msg'] = "获取模板消息成功"; $data['status'] = 1; exit(json_encode($data)); }else{ $data['msg'] = "获取模板消息失败"; $data['status'] = 0; exit(json_encode($data)); } } $data['msg'] = "获取模板消息失败"; $data['status'] = 0; exit(json_encode($data)); } //获取token public function ajaxGetToken() { $_id = input('post._id/d'); $where = array('_id' => $_id); $mpArr=db('Wxaccount')->where(array("id"=>$_id))->find(); if(empty($mpArr)){ $data['msg'] = "非法请求"; $data['status'] = 0; exit(json_encode($data)); } $this->wxObj = new Weixin($mpArr['appid'], $mpArr['appsecret']); $access_token = $this->wxObj->getAccessToken(TRUE); if (!empty($access_token)) { $mpArr=db('Wxaccount')->where(array("id"=>$_id))->update(array("state"=>1)); $data['msg'] = "OK"; $data['status'] = 1; exit(json_encode($data)); $this->resReturn(0, 'OK!'); } else { $data['msg'] = "获取token失败"; $data['status'] = 0; exit(json_encode($data)); } } }
sendspeed.php
<?php namespace app\admin\controller; use app\admin\model\Wxaccount as WxaccountModel; use app\admin\controller\Base; use think\Cache; class Sendspeed extends Base { protected $wxObj; protected $keySize; public function __construct() { parent::__construct(); $this->keySize = 1000; } public function lst() { // $list = ArticleModel::paginate(3); // $list=db('article')->alias('a')->join('cate c','c.id=a.cateid')->field('a.id,a.title,a.pic,a.author,a.state,c.catename')->paginate(3); // 2是超级管理员 if(session('uid')==2){ //$list=db('record')->paginate(10); $id = input('id')+0; //success_".$data['log_id'].".txt $path = "/www/wwwroot/www.ccc.cn/ts/"; // $path = "/"; $suc_file_path = $path."success_".$id.".txt"; $fai_file_path = $path."failed_".$id.".txt"; if(!$id){ $logs = db('log')->order('lid desc')->limit(1)->find(); }else{ $logs = db('log')->where(array('lid'=>$id))->limit(1)->find(); } if(file_exists($suc_file_path)){ $count = intval(file_get_contents($suc_file_path)); if($count > 0) $new_count = $count; else $new_count = 0; }else{ $new_count = 0; } if(file_exists($fai_file_path)){ $count1 = intval(file_get_contents($fai_file_path)); if($count1 > 0) $new_count1 = $count1; else $new_count1 = 0; }else{ $new_count1 = 0; } $arr['data'][0]['log_id'] = $logs['lid']; $arr['data'][0]['ok'] =$new_count; $arr['data'][0]['no']=$new_count1; $arr['data'][0]['fans']=$logs['fans']; }else{ exit('暂不支持'); } //print_r($list);exit; $this->assign('name',$logs['name']); $this->assign('log_id',$arr['data'][0]['log_id']); $this->assign('success',$arr['data'][0]['ok']); $this->assign('failed',$arr['data'][0]['no']); $this->assign('total',$arr['data'][0]['fans']); //print_r($arr);exit; // $this->success('添加微信公众号成功!','addmin/lst'); //$this->assign('list',$list); return $this->fetch(); } //ajax public function lst2() { // $list = ArticleModel::paginate(3); // $list=db('article')->alias('a')->join('cate c','c.id=a.cateid')->field('a.id,a.title,a.pic,a.author,a.state,c.catename')->paginate(3); // 2是超级管理员 if(session('uid')==2){ //$list=db('record')->paginate(10); $id = input('id')+0; //http://www.wxts.com/admin/sendspeed/lst/id/3 //取得最后一个id if(!$id){ $logs = db('log')->order('lid desc')->limit(1)->find(); }else{ $logs = db('log')->where(array('lid'=>$id))->limit(1)->find(); } //success_".$data['log_id'].".txt $path = "/www/wwwroot/www.ccc.cn/ts/"; //$path = "/"; $suc_file_path = $path."success_".$id.".txt"; $fai_file_path = $path."failed_".$id.".txt"; if(!$id){ $logs = db('log')->order('lid desc')->limit(1)->find(); }else{ $logs = db('log')->where(array('lid'=>$id))->limit(1)->find(); } if(file_exists($suc_file_path)){ $count = intval(file_get_contents($suc_file_path)); if($count > 0) $new_count = $count; else $new_count = 0; }else{ $new_count = 0; } if(file_exists($fai_file_path)){ $count1 = intval(file_get_contents($fai_file_path)); if($count1 > 0) $new_count1 = $count1; else $new_count1 = 0; }else{ $new_count1 = 0; } $arr['data'][0]['log_id'] = $logs['lid']; $arr['data'][0]['ok'] =$new_count; $arr['data'][0]['no']=$new_count1; $arr['data'][0]['fans']=$logs['fans']; //echo db('log')->getLastSql(); //$list = WxaccountModel::paginate(10); } $data['log_id'] = $arr['data'][0]['log_id']; $data['success'] = $arr['data'][0]['ok']; $data['failed'] = $arr['data'][0]['no']; $data['total'] = $arr['data'][0]['fans']; if(($data['success']+$data['failed'])==$data['total']){ $data['isEnd'] = 1; //做记录 全都完成后做记录 db('record')->insertGetId($data); }else{ $data['isEnd'] = 0; //Db::name('user')->insertGetId($data); } exit(json_encode($data)); // $this->success('添加微信公众号成功!','addmin/lst'); } public function lst1() { // $list = ArticleModel::paginate(3); // $list=db('article')->alias('a')->join('cate c','c.id=a.cateid')->field('a.id,a.title,a.pic,a.author,a.state,c.catename')->paginate(3); // 2是超级管理员 if(session('uid')==2){ $list=db('log')->alias('a')->join('record c','c.log_id=a.lid')->field('a.fans,a.name,c.failed,c.log_id,c.`success` as ok, c.`failed` as no')->group('c.log_id')->paginate(30); //echo db('log')->getLastSql(); //$list = WxaccountModel::paginate(10); } else{ $list=db('log')->alias('a')->join('record c','c.log_id=a.lid')->field('a.fans,a.name,c.failed,c.log_id,c.`success` as ok,c.`failed` as no')->group('c.log_id')->paginate(30); } // print_r($list);exit; // $this->success('添加微信公众号成功!','addmin/lst'); $this->assign('list',$list); return $this->fetch(); } // public function add() // { // if(request()->isPost()){ // $data=[ // 'appid'=>input('appid'), // 'appsecret'=>input('appsecret'), // 'name'=>input('name'), // 'num'=>input('num'), // 'time'=>time(), // 'uid'=>session('uid'), // ]; // $validate = \think\Loader::validate('Wxaccount'); // if(!$validate->scene('add')->check($data)){ // $this->error($validate->getError()); die; // } // if(db('wxaccount')->insert($data)){ // // Cache::rm('wxaccount'); // return $this->success('添加微信公众号成功!','lst'); // }else{ // return $this->error('添加微信公众号!'); // } // return; // } // return $this->fetch(); // } // public function edit(){ // $id=input('id'); // $articles=db('Wxaccount')->find($id); // if(request()->isPost()){ // $data=[ // 'id'=>input('id'), // 'appid'=>input('appid'), // 'appsecret'=>input('appsecret'), // 'name'=>input('name'), // 'num'=>input('num'), // 'time'=>time(), // 'uid'=>session('uid'), // ]; // $validate = \think\Loader::validate('Wxaccount'); // if(!$validate->scene('edit')->check($data)){ // $this->error($validate->getError()); die; // } // if(db('Wxaccount')->update($data)){ // $this->success('修改微信公众号成功!','lst'); // }else{ // $this->error('修改微信公众号失败!'); // } // return; // } // $this->assign('articles',$articles); // return $this->fetch(); // } // public function del(){ // $id=input('id'); // if(db('Wxaccount')->delete(input('id'))){ // $this->success('删除修改微信公众号成功!','lst'); // }else{ // $this->error('删除修改微信公众号失败!'); // } // } // //获取粉丝的 模仿之前之前那个哥们写的 // public function ajaxGetOpenids() { // $_id = input('post._id/d'); // $mpArr=db('Wxaccount')->where(array("id"=>$_id))->find(); // if(empty($mpArr)){ // $data['msg'] = "非法请求"; // $data['status'] = 0; // exit(json_encode($data)); // } // $this->wxObj = new Weixin($mpArr['appid'], $mpArr['appsecret']); // $current = 0; // $next_openid = ''; // $total = 0; // //9_3JM_N1lL2h0aZPM52tVaeL_lB3wAtYbiEddXUZa6Q4eY7A9OSsavROvzPlJMwGQNbW-_9F2D_qdc6On7m5o1Szhb_cl1zPBuUPFp_iLodq_doT6NkS-MImV0fyn_K9ybeBWh4ueEWV2fVF6pEEJfAJAIIN // // print_r($this->getOpenidList($_id, $next_openid));exit; // while ($openidArr = $this->getOpenidList($_id, $next_openid)) { // /* // Array // ( // [total] => 2 // [count] => 2 // [data] => Array // ( // [openid] => Array // ( // [0] => o9SW-jlAsvqneQWkfloZd_wLHi0s // [1] => o9SW-jvmfKEuKAJkZpdn6_exjTtA // ) // ) // [next_openid] => o9SW-jvmfKEuKAJkZpdn6_exjTtA // ) // */ // $total = $openidArr['total']; // $curKey = 0; // while ($subOpenidArr = array_slice($openidArr['data']['openid'], $curKey, $this->keySize)) { // Cache::set('openidList_' . $_id . '_' . $current, $subOpenidArr, 3600 * 24 * 7); // $current += $this->keySize; // $curKey += $this->keySize; // } // $next_openid = $openidArr['next_openid']; // } // $mpArr=db('Wxaccount')->where(array("id"=>$_id))->update(array("num"=>$total)); // // $this->mpModel->where($where)->data(array('fans' => $total))->save(); // // var_dump(S('openidList_' . $_id . '_' . 0));die; // // // // // while (Cache::get('openidList_' . $_id . '_' . $current)) { // Cache::set('openidList_' . $_id . '_' . $current, null); // $current += $this->keySize; // } // // while (S('openidList_' . $_id . '_' . $current)) { // // S('openidList_' . $_id . '_' . $current, null); // // $current += $this->keySize; // // } // $data['status'] = 1; // $data['msg'] = 'ok'; // exit(json_encode($data)); // //$this->resReturn(0, 'OK!', array('last' => $next_openid)); // // // } // protected function getOpenidList($_id = 0, $next_openid = '') { // $openidArr = $this->wxObj->getOpenidList($next_openid); // if (!empty($openidArr) && !empty($openidArr['next_openid']) && $openidArr['total'] > 0) { // return $openidArr; // } // return FALSE; // } // public function ajaxGetTplMsg() { // $_id = input('post._id/d'); // $mpArr=db('Wxaccount')->where(array("id"=>$_id))->find(); // if(empty($mpArr)){ // $data['msg'] = "非法请求"; // $data['status'] = 0; // exit(json_encode($data)); // } // $this->wxObj = new Weixin($mpArr['appid'], $mpArr['appsecret']); // $tplArr = $this->wxObj->getTemplate(); // //print_r($tplArr);exit; // if (!empty($tplArr['template_list'])) { // //$this->tplMsgModel = D('TplMsg'); // $data['tpl_list'] = $tplArr['template_list']; // db('tplmsg')->where(array('msg_id' => $_id))->delete(); // //一般情况下只会发一条 // foreach ($tplArr['template_list'] as $k => $v) { // $data = array('msg_id' => $_id, // 'template_id' => $v['template_id'], // 'title' => $v['title'], // 'primary_industry' => $v['primary_industry'], // 'deputy_industry' => $v['deputy_industry'], // 'content' => $v['content'], // 'example' => $v['example'], // 'uid'=>session('uid'), // 'time'=>time(), // ); // $ok = db('tplmsg')->insert($data); // if($ok){ // $data['msg'] = "获取模板消息成功"; // $data['status'] = 1; // exit(json_encode($data)); // }else{ // $data['msg'] = "获取模板消息失败"; // $data['status'] = 0; // exit(json_encode($data)); // } // } // } // $data['msg'] = "获取模板消息失败"; // $data['status'] = 0; // exit(json_encode($data)); // } // //获取token // public function ajaxGetToken() { // $_id = input('post._id/d'); // $where = array('_id' => $_id); // $mpArr=db('Wxaccount')->where(array("id"=>$_id))->find(); // if(empty($mpArr)){ // $data['msg'] = "非法请求"; // $data['status'] = 0; // exit(json_encode($data)); // } // $this->wxObj = new Weixin($mpArr['appid'], $mpArr['appsecret']); // $access_token = $this->wxObj->getAccessToken(TRUE); // if (!empty($access_token)) { // $mpArr=db('Wxaccount')->where(array("id"=>$_id))->update(array("state"=>1)); // $data['msg'] = "OK"; // $data['status'] = 1; // exit(json_encode($data)); // $this->resReturn(0, 'OK!'); // } else { // $data['msg'] = "获取token失败"; // $data['status'] = 0; // exit(json_encode($data)); // } // } }
发送模板消息页面 send.html
<!DOCTYPE html> <html><head> <meta charset="utf-8"> <title>推送后台</title> <meta name="description" content="Dashboard"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <!--Basic Styles--> <link href="__PS__/style/bootstrap.css" rel="stylesheet"> <link href="__PS__/style/font-awesome.css" rel="stylesheet"> <link href="__PS__/style/weather-icons.css" rel="stylesheet"> <!--Beyond styles--> <link id="beyond-link" href="__PS__/style/beyond.css" rel="stylesheet" type="text/css"> <link href="__PS__/style/demo.css" rel="stylesheet"> <link href="__PS__/style/typicons.css" rel="stylesheet"> <link href="__PS__/style/animate.css" rel="stylesheet"> <script type="text/javascript" src="__PS__/ueditor/ueditor.config.js"></script> <script type="text/javascript" src="__PS__/ueditor/ueditor.all.min.js"></script> <script type="text/javascript" src="__PS__/ueditor/lang/zh-cn/zh-cn.js"></script> </head> <body> <!-- 头部 --> {include file="common/top"} <!-- /头部 --> <div class="main-container container-fluid"> <div class="page-container"> <!-- Page Sidebar --> {include file="common/left"} <!-- /Page Sidebar --> <!-- Page Content --> <div class="page-content"> <!-- Page Breadcrumb --> <div class="page-breadcrumbs"> <ul class="breadcrumb"> <li> <a href="#">系统</a> </li> <li> <a href="{:url('kefu/lst')}">预约服务提醒进行群发</a> </li> <li class="active">预约服务提醒进行群发</li> </ul> </div> <!-- /Page Breadcrumb --> <!-- Page Body --> <div class="page-body"> <div class="row"> <div class="col-lg-12 col-sm-12 col-xs-12"> <div class="widget"> <div class="widget-header bordered-bottom bordered-blue"> <span class="widget-caption">新增客服消息</span> </div> <div class="widget-body" style="height: 1200px;"> <div id="horizontal-form"> <form class="form-horizontal" id="bd" role="form" action="" enctype="multipart/form-data" method="post"> <input type="hidden" name="_id" value="{$_id}" /> <div class="form-group"> <label for="username" class="col-sm-2 control-label no-padding-right">模板名</label> <div class="col-sm-6"> <input class="form-control" id="title" placeholder="请输入标题" name="title" type="text" value="{$tplMsgArr.title}" > </div> <p class="help-block col-sm-4 red">* 必填</p> </div> <div class="form-group"> <label for="username" class="col-sm-2 control-label no-padding-right">超链接地址</label> <div class="col-sm-6"> <input class="form-control" id="content" placeholder="请输入描述" name="url" type="text"> </div> <p class="help-block col-sm-4 red">* 必填</p> </div> <div class="form-group"> <label for="username" class="col-sm-2 control-label no-padding-right">模板id</label> <div class="col-sm-6"> <input class="form-control" id="img_url" placeholder="请输入图片链接" name="img_url" value="{$tplMsgArr.template_id}" type="text" readonly="readonly"> </div> <p class="help-block col-sm-4 red">* 必填</p> </div> {volist name="tplKeyArr" id="vo" key="tItem"} <div class="form-group"> <label for="{$vo}" class=" col-sm-2 control-label no-padding-right">{$vo}</label> <div class="col-sm-6"> <input type="text" class="form-control input_data" id="{$vo}" name="{$vo}" placeholder=""> </div> <p class="help-block col-sm-4 red">* 必填</p> </div> <div class="form-group"> <label for="color_{$vo}" class=" col-sm-2 control-label no-padding-right">字体颜色:</label> <div class="col-sm-6"> <input type="color" class="form-control input_color" id="color_{$vo}" name="color_{$vo}" placeholder="请输入字体颜色"> </div> </div> {/volist} <div class="form-group"> <label for="textarea" class=" col-sm-2 control-label no-padding-right">示例:</label> <div class="col-sm-6"> <textarea class="form-control" rows="6" disabled="disabled">{$tplMsgArr.example}</textarea> </div> </div> <div class="col-sm-offset-1" style="margin-bottom:30px;"> <h3>预览:</h2> <div class="preview">{$content}</div> </div> <!-- <div class="form-group"> <label for="username" class="col-sm-2 control-label ">预览:</label> <div class="form-group"> <p> </p> {volist name="tplKeyArr" id="vo" key="tItem"} <p style="text-align: center; margin-top: 5px;">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</p> {/volist} </div> </div --> <div class="form-group"> <label for="username" class="col-sm-2 control-label no-padding-right">openid</label> <div class="col-sm-6"> <input class="form-control" id="openid" placeholder="请输入openid不写就是群发,填写了请点击下面测试的按钮" name="openid" type="text"> </div> <p class="help-block col-sm-4 red">* 必填</p> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default">发送模板消息</button> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button id="sd" type="button" class="btn btn-default">测试带openid的模板消息</button> </div> </div> </form> </div> </div> </div> </div> </div> </div> <!-- /Page Body --> </div> <!-- /Page Content --> </div> </div> <!--Basic Scripts--> <script src="__PS__/style/jquery_002.js"></script> <script src="__PS__/style/bootstrap.js"></script> <script src="__PS__/style/jquery.js"></script> <!--Beyond Scripts--> <script src="__PS__/style/beyond.js"></script> <script type="text/javascript"> //实例化编辑器 //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例 // UE.getEditor('content',{initialFrameWidth:1000,initialFrameHeight:400,}); $('.input_data').blur(function(){ var input_name = $(this).attr('name'); var value = $(this).val(); if(value == ''){ $('.'+input_name).html('{{'+input_name+'}}'); }else{ $('.'+input_name).html(value); } }); $('.input_color').blur(function(){ var input_name = $(this).attr('name'); var value = $(this).val(); $('.'+input_name).css('color',value); }); $("#sd").on('click',function(){ var url = window.location.href; //alert($('form').serialize()); //return false; $.ajax({ //提交数据的类型 POST GET type:"POST", //提交的网址 url:url, //提交的数据 data:$('form').serialize(), //返回数据的格式 datatype: "json",//"xml", "html", "script", "json", "jsonp", "text". //成功返回之后调用的函数 success:function(data){ var dataObj=eval("("+data+")"); if(dataObj.status==1){ alert("发送成功"); }else{ alert("发送失败"); } }, //调用出错执行的函数 error: function(){ alert("服务器错误,请与管理员联系"); } }); // $.ajax({ // type: 'POST', // url: url, // data: $('form').serialize(), // dataType: 'json', // success: success, // }); // $("#bd").submit(); }); </script> </body></html>
获取进度页面 lst
<!DOCTYPE html> <html><head> <meta charset="utf-8"> <title>推送后台</title> <meta name="description" content="Dashboard"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <!--Basic Styles--> <link href="__PS__ /style/bootstrap.css" rel="stylesheet"> <link href="__PS__ /style/font-awesome.css" rel="stylesheet"> <link href="__PS__ /style/weather-icons.css" rel="stylesheet"> <!--Beyond styles--> <link id="beyond-link" href="__PS__ /style/beyond.css" rel="stylesheet" type="text/css"> <link href="__PS__ /style/demo.css" rel="stylesheet"> <link href="__PS__ /style/typicons.css" rel="stylesheet"> <link href="__PS__ /style/animate.css" rel="stylesheet"> </head> <body> <!-- 头部 --> {include file="common/top"} <!-- /头部 --> <div class="main-container container-fluid"> <div class="page-container"> <!-- Page Sidebar --> {include file="common/left"} <!-- /Page Sidebar --> <!-- Page Content --> <div class="page-content"> <!-- Page Breadcrumb --> <div class="page-breadcrumbs"> <ul class="breadcrumb"> <li> <a href="#">系统</a> </li> <li class="active">发送进度管理</li> </ul> </div> <!-- /Page Breadcrumb --> <!-- Page Body --> <div class="page-body"> <button type="button" tooltip="查看全部" class="btn btn-sm btn-azure btn-addon" onClick="javascript:window.location.href = '{:url('tplmsg/lst')}'"> <i class="fa fa-plus"></i> 跳转 </button> <div class="row"> <div class="col-lg-12 col-sm-12 col-xs-12"> <div class="widget"> <div class="widget-body"> <div class="flip-scroll"> <table class="table table-bordered table-hover"> <thead class=""> <tr> <th class="text-center" width="4%">ID</th> <th class="text-center">公众号名称</th> <th class="text-center">粉丝数</th> <th class="text-center">成功</th> <th class="text-center">失败</th> </tr> </thead> <tbody> <tr> <td align="center">{$log_id}</td> <td align="center">{$name}</td> <td align="center">{$total}</td> <td align="center" class="success" >{$success}</td> <td align="center" class="failed" >{$failed}</td> </tr> </tbody> </table> </div> </div> </div> </div> </div> </div> <!-- /Page Body --> </div> <!-- /Page Content --> </div> </div> <!--Basic Scripts--> <script src="__PS__ /style/jquery_002.js"></script> <script src="__PS__ /style/bootstrap.js"></script> <script src="__PS__ /style/jquery.js"></script> <!--Beyond Scripts--> <script src="__PS__ /style/beyond.js"></script> {literal} <script> var log_id = {$log_id}; var success = {$success}; var failed = {$failed}; var total = {$total}; // alert(success); // alert(failed); // alert(total); // alert(log_id); function getSchedule(){ $.get('/admin/sendspeed/lst2/',{'id':log_id},function(d){ //{"log_id":5,"success":"1263","failed":"0","total":1263} //alert(d); $('.success').html(d.success); $('.failed').html(d.failed); if(d.isEnd == 1){ clearInterval(timer); alert('恭喜,发送完毕!') } },'json'); } if(success+failed<total){ var timer = setInterval('getSchedule()',1500); } </script> </body></html>
lst1.htm
扫描二维码关注公众号,回复:
1245348 查看本文章
<!DOCTYPE html> <html><head> <meta charset="utf-8"> <title>推送后台</title> <meta name="description" content="Dashboard"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <!--Basic Styles--> <link href="__PS__ /style/bootstrap.css" rel="stylesheet"> <link href="__PS__ /style/font-awesome.css" rel="stylesheet"> <link href="__PS__ /style/weather-icons.css" rel="stylesheet"> <!--Beyond styles--> <link id="beyond-link" href="__PS__ /style/beyond.css" rel="stylesheet" type="text/css"> <link href="__PS__ /style/demo.css" rel="stylesheet"> <link href="__PS__ /style/typicons.css" rel="stylesheet"> <link href="__PS__ /style/animate.css" rel="stylesheet"> </head> <body> <!-- 头部 --> {include file="common/top"} <!-- /头部 --> <div class="main-container container-fluid"> <div class="page-container"> <!-- Page Sidebar --> {include file="common/left"} <!-- /Page Sidebar --> <!-- Page Content --> <div class="page-content"> <!-- Page Breadcrumb --> <div class="page-breadcrumbs"> <ul class="breadcrumb"> <li> <a href="#">系统</a> </li> <li class="active">发送进度管理</li> </ul> </div> <!-- /Page Breadcrumb --> <!-- Page Body --> <div class="page-body"> <button type="button" tooltip="添加栏目" class="btn btn-sm btn-azure btn-addon" onClick="javascript:window.location.href = '{:url('tplmsg/lst')}'"> <i class="fa fa-plus"></i> 跳转 </button> <div class="row"> <div class="col-lg-12 col-sm-12 col-xs-12"> <div class="widget"> <div class="widget-body"> <div class="flip-scroll"> <table class="table table-bordered table-hover"> <thead class=""> <tr> <th class="text-center" width="4%">ID</th> <th class="text-center">公众号名称</th> <th class="text-center">粉丝数</th> <th class="text-center">成功</th> <th class="text-center">失败</th> </tr> </thead> <tbody> {volist name="list" id="vo" key="key"} <tr> <td align="center">{$key}</td> <td align="center">{$vo.name}</td> <td align="center">{$vo.fans}</td> <td align="center">{$vo.ok}</td> <td align="center">{$vo.no}</td> </tr> {/volist} </tbody> </table> </div> <div style="text-align:right; margin-top:10px;"> {$list->render()} </div> </div> </div> </div> </div> </div> <!-- /Page Body --> </div> <!-- /Page Content --> </div> </div> <!--Basic Scripts--> <script src="__PS__ /style/jquery_002.js"></script> <script src="__PS__ /style/bootstrap.js"></script> <script src="__PS__ /style/jquery.js"></script> <!--Beyond Scripts--> <script src="__PS__ /style/beyond.js"></script> </body></html>
wxaccount里 获取粉丝等信息的页面
<!DOCTYPE html> <html><head> <meta charset="utf-8"> <title>推送后台</title> <meta name="description" content="Dashboard"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <!--Basic Styles--> <link href="__PUBLIC__ /style/bootstrap.css" rel="stylesheet"> <link href="__PUBLIC__ /style/font-awesome.css" rel="stylesheet"> <link href="__PUBLIC__ /style/weather-icons.css" rel="stylesheet"> <!--Beyond styles--> <link id="beyond-link" href="__PUBLIC__ /style/beyond.css" rel="stylesheet" type="text/css"> <link href="__PUBLIC__ /style/demo.css" rel="stylesheet"> <link href="__PUBLIC__ /style/typicons.css" rel="stylesheet"> <link href="__PUBLIC__ /style/animate.css" rel="stylesheet"> </head> <body> <!-- 头部 --> {include file="common/top"} <!-- /头部 --> <div class="main-container container-fluid"> <div class="page-container"> <!-- Page Sidebar --> {include file="common/left"} <!-- /Page Sidebar --> <!-- Page Content --> <div class="page-content"> <!-- Page Breadcrumb --> <div class="page-breadcrumbs"> <ul class="breadcrumb"> <li> <a href="#">系统</a> </li> <li class="active">公众号管理</li> </ul> </div> <!-- /Page Breadcrumb --> <!-- Page Body --> <div class="page-body"> <button type="button" tooltip="添加栏目" class="btn btn-sm btn-azure btn-addon" onClick="javascript:window.location.href = '{:url('wxaccount/add')}'"> <i class="fa fa-plus"></i> Add </button> <div class="row"> <div class="col-lg-12 col-sm-12 col-xs-12"> <div class="widget"> <div class="widget-body"> <div class="flip-scroll"> <table class="table table-bordered table-hover"> <thead class=""> <tr> <th class="text-center" width="4%">ID</th> <th class="text-center">公众号id</th> <th class="text-center">公众号名</th> <th class="text-center">粉丝数</th> <th class="text-center">操作粉丝</th> <th class="text-center">操作模板消息</th> <th class="text-center">操作客服消息</th> <th class="text-center">状态</th> <th class="text-center">操作令牌</th> <th class="text-center" width="14%">操作</th> </tr> </thead> <tbody> {volist name="list" id="vo"} <tr> <td align="center">{$vo.id}</td> <td align="center">{$vo.appid}</td> <td align="center">{$vo.name}</td> <td align="center">{$vo.num}</td> <td align="center"> <a href="javascript::void(0);" class="btn btn-primary btn-sm shiny" onclick="getOpenids({$vo.id})"> <i class="fa fa-edit"></i> 重新获取粉丝 </a> </td> <td align="center"> <a href="javascript::void(0);" class="btn btn-primary btn-sm shiny" onclick="getTplMsg({$vo.id})" > <i class="fa fa-edit"></i> 获取模板消息 </a> </td> <td align="center"> <a href="{:url('wxaccount/edit',array('id'=>$vo['id']))}" class="btn btn-primary btn-sm shiny"> <i class="fa fa-edit"></i> 设置发送客服消息 </a> </td> <td align="center"> {if condition="$vo['state'] eq 1 "} 令牌有效 {else /} 令牌失效 {/if} </td> <td align="center"> <a href="javascript::void(0);" class="btn btn-primary btn-sm shiny" onclick="getAccessToken({$vo.id})"> <i class="fa fa-edit"></i> 重获令牌 </a> </td> <td align="center"> <a href="{:url('wxaccount/edit',array('id'=>$vo['id']))}" class="btn btn-primary btn-sm shiny"> <i class="fa fa-edit"></i> 修改公众号 </a> <a href="#" onClick="warning('确实要删除吗', '{:url('wxaccount/del',array('id'=>$vo['id']))}')" class="btn btn-danger btn-sm shiny"> <i class="fa fa-trash-o"></i> 删除公众号 </a> </td> </tr> {/volist} </tbody> </table> </div> <div style="text-align:right; margin-top:10px;"> {$list->render()} </div> </div> </div> </div> </div> </div> <!-- /Page Body --> </div> <!-- /Page Content --> </div> </div> <!--Basic Scripts--> <script src="__PUBLIC__ /style/jquery_002.js"></script> <script src="__PUBLIC__ /style/bootstrap.js"></script> <script src="__PUBLIC__ /style/jquery.js"></script> <!--Beyond Scripts--> <script src="__PUBLIC__ /style/beyond.js"></script> <script type="text/javascript"> function getOpenids(_id){ $.post('/Admin/Wxaccount/ajaxGetOpenids',{'_id':_id},function(d){ alert(d.msg); window.location.reload(); },'json'); } function getTplMsg(_id){ $.post('/Admin/Wxaccount/ajaxGetTplMsg',{'_id':_id},function(d){ alert(d.msg); },'json'); } function getAccessToken(_id){ $.post('/Admin/Wxaccount/ajaxGetToken',{'_id':_id},function(d){ alert(d.msg); window.location.reload(); },'json'); } function delAccounts(_id){ alert('d'); // $.post('/Admin/MpAccounts/ajaxDelAccounts',{'_id':_id},function(d){ // alert(d.msg); // window.location.reload(); // },'json'); } </script> </body></html>
swoole client 异步
<?php class Swclient { public function send($msg){ $client = new \swoole_client(SWOOLE_SOCK_TCP); // $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); //连接到服务器 if (!$client->connect('127.0.0.1', 9501, 1)) { $this->write("connect failed."); } //向服务器发送数据 if (!$client->send($msg)) { $this->write("send ".$msg." failed."); } //关闭连接 $client->close(); } private function write($str){ $path = "/sys.log"; $str = "[".date("Y-m-d H:i:s")."]".$str; $str .= PHP_EOL; file_put_contents($path,$str,FILE_APPEND); } } $redis = new \Redis; $redis->connect('127.0.0.1', 6379); $key= $argv[1]; //$s = unserialize($redis->get($key)); $s = json_decode($redis->get($key),true); file_put_contents("0.txt",$s); $serv = new Swclient(); //$serv->send(1); foreach($s as $k=>$v){ file_put_contents("cb.txt",serialize($v).PHP_EOL,FILE_APPEND); file_put_contents("cscb.txt","1".PHP_EOL,FILE_APPEND); $serv->send(serialize($v)); } ?>
swoole server.php
<?php $serv = new swoole_server("127.0.0.1", 9501); //设置异步任务的工作进程数量 $serv->set(array( 'worker_num' => 16, 'daemonize' => true, 'max_request' => 200000, 'dispatch_mode' => 2, 'debug_mode'=> 1, 'task_worker_num' =>300 )); //监听数据接收事件 $serv->on('receive', function($serv, $fd, $from_id, $data) { //投递异步任务 $task_id = $serv->task($data);//非阻塞 echo "同步代码执行完成\n"; }); //处理异步任务 $serv->on('task', function ($serv, $task_id, $from_id, $data) { $res = handleFun($data); //返回任务执行的结果 $serv->finish($res); }); //处理异步任务的结果 $serv->on('finish', function ($serv, $task_id, $data) { // print_r($data); // // $pdo = new PDO( // "mysql:host=localhost;port=3306;dbname=wxsm", // "root", // "hust.", // array( // PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8';", // PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // PDO::ATTR_PERSISTENT => true // ) // ); // $sql = array( // 'sql'=>'insert into tp_record (`log_id`,`success`,`failed` ) values(?,?,?)', // 'param' => array( // $data['log_id'], // $data['success'], // $data['failed'] // ), // ); $suc_name="success_".$data['log_id'].".txt"; $fil_name="failed_".$data['log_id'].".txt"; if(file_exists('/www/wwwroot/www.ss.cn/ts/'.$suc_name)){ $count = intval(file_get_contents('/www/wwwroot/www.ss.cn/ts/'.$suc_name)); if($count > 0) $new_count = $count+$data['success']; else $new_count = $data['success']; file_put_contents('/www/wwwroot/www.ss.cn/ts/'.$suc_name,$new_count); }else{ $new_count = $data['success']; file_put_contents('/www/wwwroot/www.ss.cn/ts/'.$suc_name,$new_count); } if(file_exists('/www/wwwroot/www.ss.cn/ts/'.$fil_name)){ $count = intval(file_get_contents('/www/wwwroot/www.ss.cn/ts/'.$fil_name)); if($count > 0) $new_count = $count+$data['failed']; else $new_count = $data['failed']; file_put_contents('/www/wwwroot/www.ss.cn/ts/'.$fil_name,$new_count); }else{ $new_count = $data['failed']; file_put_contents('/www/wwwroot/www.ss.cn/ts/'.$fil_name,$new_count); } // $count1 = intval(file_get_contents($fil_name)); // if($count1 > 0) $new_count1 = $count1+$data['failed']; // else $new_count1 = $data['failed']; // file_put_contents($fil_name,$new_count1); file_put_contents('/www/wwwroot/www.ss.cn/ts/swoole.log', date('Y-m-d H:i:s') . ' ' . 'Success:' . $data['success'] . ',Failed:' . $data['failed'] . ',tpl_id:' . $data['tpl_id'] . PHP_EOL, FILE_APPEND); echo "id".$task_id."异步任务执行完成"; }); $serv->start(); function handleFun($data){ $success = 0; $failed = 0; // $data=json_decode($data,true); // foreach ($data as $key => $value) { // $shuju = json_decode($data,true); $shuju = unserialize($data); // print_r($shuju);exit; // $nums = count($shuju['ids']); /* Array ( [wxurl] => https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=9_cP1mSfG5gaINSG-raKFNE2HchHHSutyNyblwAIOJNHOm8-WMZxaB97TNe2PLu-kyFwJQr-LbLHlEWV4XPXHZV0FugBZB_6BDjQUd3IlP3QrgwUDGwSyGV8uwmT4St4S-Ocvy-BpXx1leN4cGHPLeAEAYGC [ids] => Array ( [0] => oq05X0ZtU-ZjuRlL2YfGQtZa2tzk [1] => oq05X0TWuci3IAcDDo2jndETTaDo [2] => oq05X0XDyiIBrCuF7TU6pos-0A7g [3] => oq05X0R2REqidElYy92AGmoCD7wQ [4] => oq05X0UrTpQjf3bwi8C4cDi4I_Y8 [5] => oq05X0X5BaJtjHAW0867LpYZkz3Y [6] => oq05X0Z2UEWHT1dnN4InBkYvPUDQ [7] => oq05X0XyU8SXMM02sAQtIruaVpRA [8] => oq05X0RHmqJ3_135jut2qrjB8QEM [9] => oq05X0e2q8zTbJP7JT41OVpZ8k7g [10] => oq05X0bnosfgc9nScYNIo2xYMSVg [11] => oq05X0dwl2W6txEkTqivawOcvLLw [12] => oq05X0ZU1HFasId5MiRG5pFHQJLQ [13] => oq05X0a9EKYS8WPCNe53JEgHOXyU [14] => oq05X0Rp6jL_wpI0Vnv4Ae7CyoWA [15] => oq05X0dPGmPWB1Jo2P1oDtXTRbtk [16] => oq05X0QD3Y7Mmfi1yCPUl2-sKf3Q [17] => oq05X0WRzzw5AzzDcR3uGo4vnnxc [18] => oq05X0cl9Hy9OSxj1uESMzfXmzxU [19] => oq05X0V0DKTuUmd13yQqjF8rafUg [20] => oq05X0b9LGUPiHB4lXkXQ1V1kzH8 [21] => oq05X0cSVqFuqIyWjNx8kRaXR4Q0 [22] => oq05X0RM9UBuxYfz-tNgyayP2HCo [23] => oq05X0X3icZsr_2dScEx4d7zMo_I [24] => oq05X0TsTmn8_1at68iMOBRYQpoE [25] => oq05X0U68I7SQrPgyytRexAzlVVc [26] => oq05X0ZOrtDi1pFOkny5PKTyt_lc [27] => oq05X0ckO6d034NQrE2QMp9PpVwI [28] => oq05X0YipbYedoz-cCvgVYgLkRG0 [29] => oq05X0SYEB9uQNXc-dmM82f4M0vs [30] => oq05X0dnyCOWA6CpzBO7MIIR683A [31] => oq05X0dskScKB_azVM6vnTtvrjpI [32] => oq05X0WxR4g2edQwQV9nRQtAoVAo [33] => oq05X0TufTgOLIr_7Vzl3kB4pzv0 [34] => oq05X0TJH00m4RYNj3hOAuTMDg18 [35] => oq05X0axoguYkLSlgOEvqA_QZv4E [36] => oq05X0eIbxTHqfyOpCbLZuv7TaI0 [37] => oq05X0UMORLLcFpGGczFp4Arf220 [38] => oq05X0Zcd49ADoIUUeX-aHqY4080 [39] => oq05X0aZT8GiuQc75v3buaTctq84 [40] => oq05X0YRh7VX8PeVBIFe-rZmKqxY [41] => oq05X0c0kV7VNuIBu1aMNHIZA38g [42] => oq05X0TSp6wvJriljrrWMjjXbo90 [43] => oq05X0VriXEiubnlphGZ-pfwN0W8 [44] => oq05X0bUxvirRVLNih7tCYizN5_Y [45] => oq05X0SJoqfMKKLNOQ_e9-dnTv4Y [46] => oq05X0VvMe9d7oPzc921xHCGefVE [47] => oq05X0ZFvWcILqVkThUJu6blrsrw [48] => oq05X0QYBDEW2pd8G8binGvet0cA [49] => oq05X0coLyNRJzDm2WhQ8amXcNIc ) [data] => Array ( [template_id] => 7AZ2nWakhTnuYt-nHUCCGY_pZXn4Wxv64hTUMwkruBg [url] => [data] => Array ( [first] => Array ( [value] => 1 [color] => #000000 ) [keyword1] => Array ( [value] => 2 [color] => #000000 ) [keyword2] => Array ( [value] => 2 [color] => #000000 ) [remark] => Array ( [value] => 3 [color] => #000000 ) ) ) ) */ // $url=$data;//调用发送模板消息接口,服务端没办法直接获取微信的接口的一些数据,此处做了一些加密 // $postUrl = $shuju['wxurl']; $postUrl = $shuju['wxurl']; // file_put_contents("sss.txt",$shuju['wxurl']); // file_put_contents("urlurl.txt",$postUrl); $curlPost = $shuju['data']; //$curlPost = 1; //print_r($shuju['ids']); /*$nums= count($shuju['ids']); for($i=0;$i<$nums;$i++){ file_put_contents('oids.txt',$shuju['ids'][$i].PHP_EOL, FILE_APPEND); } */ /* 'tpl_id' => $_id, 'mp_id' => $tplMsgArr['msg_id'], 'log_id' => $logId, */ for($i=0;$i<$nums;$i++){ //$data['touser'] = "oq05X0SgNIuJGG_3ByDRKFTVxtNA"; $curlPost['touser'] = $shuju['ids'][$i]; // $curlPost['touser'] = "oq05X0SgNIuJGG_3ByDRKFTVxtNA"; // file_put_contents('opend.txt',$curlPost['touser'].PHP_EOL, FILE_APPEND); // print_r($curlPost); /* Array ( [template_id] => 7AZ2nWakhTnuYt-nHUCCGY_pZXn4Wxv64hTUMwkruBg [url] => [data] => Array ( [first] => Array ( [value] => 1 [color] => #000000 ) [keyword1] => Array ( [value] => 1 [color] => #000000 ) [keyword2] => Array ( [value] => [color] => #000000 ) [remark] => Array ( [value] => [color] => #000000 ) ) [touser] => oq05X0fzWbQxoJQtJlDYOJjAzGd0 ) */ //echo $postUrl; //print_r($curlPost); // file_put_contents("oo.txt",$curlPost); $ret_json= httpPost($postUrl,json_encode($curlPost)); // file_put_contents("sv.txt",$ret_json); $res = json_decode($ret_json,true); //print_r($res); if ($res['errcode'] == 0 && $res['errmsg'] == 'ok') { $success++; // file_put_contents('/tmp/tplmsg_res.log', date('Y-m-d H:i:s') . ' result success tpl_id:' . $dataArr['tpl_id'] . ' openid ' . $v . PHP_EOL, FILE_APPEND); } else { $failed++; file_put_contents('/www/wwwroot/www.ss.cn/ts/tplmsg_res.log', date('Y-m-d H:i:s') . ' result Failed tpl_id ' . $shuju['tpl_id'] . ' errcode ' . $res['errcode'] . ' errmsg ' . $res['errmsg'] . ',openid:' . $shuju['ids'][$i] . PHP_EOL, FILE_APPEND); } } $ret_arr['tpl_id'] = $shuju['tpl_id']; $ret_arr['log_id'] = $shuju['log_id']; $ret_arr['success'] = $success; $ret_arr['failed'] = $failed; return $ret_arr; } function httpPost($url, $data = null, $time = 10) { //print_r($data); $ch = curl_init(); //curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); curl_setopt($ch, CURLOPT_TIMEOUT, $time); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $temp = curl_exec($ch); if (curl_errno($ch)) { return curl_error($ch); } curl_close($ch); return $temp; }
代码比较乱 大体如上 整理完成