diff --git a/application/wechat/controller/News.php b/application/wechat/controller/News.php index 047e2086b..4138e05f0 100644 --- a/application/wechat/controller/News.php +++ b/application/wechat/controller/News.php @@ -14,10 +14,14 @@ namespace app\wechat\controller; +use Exception; +use think\Db; +use think\Log; +use think\response\View; use controller\BasicAdmin; use service\DataService; +use service\FileService; use service\WechatService; -use think\Db; /** * 微信图文管理 @@ -55,7 +59,7 @@ class News extends BasicAdmin { /** * 添加图文 - * @return \think\response\View + * @return View */ public function add() { if ($this->request->isGet()) { @@ -75,7 +79,7 @@ class News extends BasicAdmin { /** * 编辑图文 - * @return \think\response\View + * @return View */ public function edit() { $id = $this->request->get('id', ''); @@ -118,13 +122,6 @@ class News extends BasicAdmin { return join(',', $ids); } - /** - * 图文推送 - */ - public function push() { - - } - /** * 删除图文 */ @@ -140,7 +137,7 @@ class News extends BasicAdmin { Db::name('WechatNews')->where('id', $id)->delete(); Db::commit(); $isSuccess = true; - } catch (\Exception $e) { + } catch (Exception $e) { Db::rollback(); } (isset($isSuccess) && $isSuccess) && $this->success('图文删除成功!'); @@ -156,4 +153,115 @@ class News extends BasicAdmin { return '开发中'; } + /** + * 推荐图文 + * @return array|void + */ + public function push() { + # 获取将要推送的粉丝列表 + $params = $this->request->post('group', ''); + $ids = explode(',', $params); + $fansDb = Db::name('WechatFans'); + $news_id = $this->request->get('id', ''); + switch (strtolower($this->request->get('action', ''))) { + case 'getgroup': + if (!in_array('0', $ids)) { + $fansDb->where("concat(',',tagid_list,',') REGEXP '," . join(',|,', $ids) . ",'"); + } + return ['code' => "SUCCESS", 'data' => $fansDb->where('subscribe', '1')->column('openid,nickname')]; + case 'getuser': + if (!in_array('0', $ids)) { + $fansDb->where("concat(',',tagid_list,',') REGEXP '," . join(',|,', $ids) . ",'"); + } + return ['code' => "SUCCESS", 'data' => $fansDb->where('subscribe', '1')->column('openid,nickname')]; + default : + // 显示及图文 + $newsinfo = WechatService::getNewsById($news_id); + // Get 请求,显示选择器界面 + if ($this->request->isGet()) { + $fans_tags = Db::name('WechatFansTags')->select(); + array_unshift($fans_tags, [ + 'id' => 0, + 'name' => '全部', + 'count' => Db::name('WechatFans')->where('subscribe', '1')->count(), + ]); + return view('push', ['vo' => $newsinfo, 'fans_tags' => $fans_tags]); + } + // Post 请求,执行图文推送操作 + $post = $this->request->post(); + empty($post['fans_tags']) && $this->error('还没有选择要粉丝对象!'); + // 图文上传操作 + !$this->_uploadWechatNews($newsinfo) && $this->error('图文上传失败,请稍候再试!'); + // 数据拼装 + $data = []; + if (in_array('0', $post['fans_tags'])) { + $data['msgtype'] = 'mpnews'; + $data['filter'] = ['is_to_all' => true]; + $data['mpnews'] = ['media_id' => $newsinfo['media_id']]; + } else { + $data['msgtype'] = 'mpnews'; + $data['filter'] = ['is_to_all' => false, 'tag_id' => join(',', $post['fans_tags'])]; + $data['mpnews'] = ['media_id' => $newsinfo['media_id']]; + } + $wechat = &load_wechat('Receive'); + (FALSE !== $wechat->sendGroupMassMessage($data)) && $this->success('微信图文推送成功!'); + $this->error("微信图文推送失败,{$wechat->errMsg} [{$wechat->errCode}]"); + } + } + + /** + * 上传永久图文 + * @param type $newsinfo + * @return boolean + */ + private function _uploadWechatNews(&$newsinfo) { + $self = $this; + foreach ($newsinfo['articles'] as &$article) { + $article['thumb_media_id'] = WechatService::uploadForeverMedia($article['local_url']); + $article['content'] = preg_replace_callback("/<img(.*?)src=['\"](.*?)['\"](.*?)\/?>/i", function ($matches) use ($self) { + $src = $self->_filterWechatImage($matches[2]); + return "<img{$matches[1]}src=\"{$src}\"{$matches[3]}/>"; + }, htmlspecialchars_decode($article['content'])); + } + $wechat = & load_wechat('media'); + // 如果已经上传过,先删除之前的历史记录 + !empty($newsinfo['media_id']) && $wechat->delForeverMedia($newsinfo['media_id']); + // 上传图文到微信服务器 + $result = $wechat->uploadForeverArticles(['articles' => $newsinfo['articles']]); + if (isset($result['media_id'])) { + $newsinfo['media_id'] = $result['media_id']; + return Db::name('WechatNews')->where('id', $newsinfo['id'])->update(['media_id' => $result['media_id']]); + } + Log::error("上传永久图文失败, {$wechat->errMsg}[{$wechat->errCode}]"); + return false; + } + + /** + * 文章内容图片处理 + * @param string $local_url + * @return string|null + */ + private function _filterWechatImage($local_url = '') { + # 检测图片是否已经上传过了 + $img = Db::name('WechatNewsImage')->where('local_url', $local_url)->find(); + if (!empty($img) && isset($img['media_url'])) { + return $img['media_url']; + } + # 下载临时文件到本地 + $filename = 'wechat/image/' . join('/', str_split(md5($local_url), 16)) . '.' . strtolower(pathinfo($local_url, 4)); + $result = FileService::local($filename, file_get_contents($local_url)); + if ($result && isset($result['file'])) { + # 上传图片到微信服务器 + $wechat = &load_wechat('media'); + $mediainfo = $wechat->uploadImg(['media' => "@{$result['file']}"]); + if (!empty($mediainfo)) { + $data = ['local_url' => $local_url, 'media_url' => $mediainfo['url'], 'md5' => md5($local_url)]; + Db::name('WechatNewsImage')->insert($data); + return $mediainfo['url']; + } + } + Log::error("图片上传失败,请稍后再试!{$wechat->errMsg}[{$wechat->errCode}]"); + return null; + } + } diff --git a/application/wechat/view/news.index.html b/application/wechat/view/news.index.html index 1090373ce..88e007c9b 100644 --- a/application/wechat/view/news.index.html +++ b/application/wechat/view/news.index.html @@ -12,7 +12,7 @@ {foreach $list as $vo} <div class="news_item"> <div class='news_tools hide'> - <a href='javascript:alert("开发中...")'>推送</a> + <a data-modal="{:url('push')}?id={$vo.id}" href='javascript:void(0)'>推送</a> <a data-open='{:url("edit")}?id={$vo.id}' href='javascript:void(0)'>编辑</a> <a data-news-del="{$vo.id}" href='javascript:void(0)'>删除</a> </div> diff --git a/application/wechat/view/news.push.html b/application/wechat/view/news.push.html new file mode 100644 index 000000000..2bf5155ed --- /dev/null +++ b/application/wechat/view/news.push.html @@ -0,0 +1,112 @@ +<form data-auto='true' action='__SELF__'> + + <div class="col-xs-2 news-container"> + <h5 class="text-center" style="margin:10px 0">微信图文</h5> + <div class="news-box"> + {foreach $vo.articles as $key=>$value} + <div class="news-item transition" data-id="{$value.id}"> + <div class="news-image" style='background-image:url({$value.local_url})'></div> + <span class="news-title">{$value.title}</span> + </div> + <hr/> + {/foreach} + </div> + </div> + + <div class="col-xs-2 list-container"> + <h5 class="text-center" style="margin:10px 0">指定粉丝标签推送 <a data-check-all> 全选 </a></h5> + <div class="list-item"> + + {foreach $fans_tags as $tag} + <label class="cuci-lable"> + <input name="fans_tags[]" value='{$tag.id}' type="checkbox"/> {$tag.name} ({$tag.count}) + </label> + {/foreach} + + {literal} + <script id="push" type="text/template"> + {{if data}} + {{each data as value}} + <label class="cuci-lable"> + {{value.nickname}} + </label> + {{/each}} + {{if (data.length > 199)}} + <label class="cuci-lable"> + ... + </label> + {{/if}} + {{else}} + <h5></h5> + {{/if}} + </script> + {/literal} + + <script> + require(['jquery', 'template'], function () { + var $allbtn = $('[data-check-all]').on('click', function () { + var check_status = check_checked(); + /*重置和全选数据变化处理*/ + $('input[name*=fans_tags]').map(function () { + this.checked = !check_status; + }); + check_checked(); + postpush(); + }); + /*重置和全选的效果处理*/ + function check_checked() { + var allcheck = true; + $('input[name*=fans_tags]').map(function () { + (!this.checked) && (allcheck = false); + }); + return ((allcheck) ? $allbtn.html('重置') : $allbtn.html('全选')), allcheck; + } + + /*点击每一个选项都触发事件*/ + $('input[name*=fans_tags]').on('click', function () { + check_checked(); + postpush(); + }); + /*数据异步获取并显示出来*/ + function postpush() { + var inp = $('input[name*=fans_tags]'); + var group = []; + for (var i = 0; i < inp.length; i++) { + if (inp[i].checked === true) { + group.push(inp[i].value); + } + } + $.post("{:url('wechat/news/push')}?action=getuser", {group: group.join(',')}, function (ret) { + var html = template('push', ret); + document.getElementById('push-tags').innerHTML = html; + }); + } + }); + </script> + </div> + <div id='push-tags' class="list-item"></div> + </div> + <div style="clear:both;height:60px"></div> + + <div class="bottom-btn text-center"> + <button class="layui-btn">立即推送图文</button> + <button type='button' data-close='' data-confirm='确定要取消推送图文吗?' class="layui-btn layui-btn-danger">取消推送图文</button> + </div> + +</form> + +<style> + body { min-width: 500px } + .bottom-btn { display: block; background: #F7F7F7; padding: 10px; position: absolute; position: fixed; bottom: 0; width: 100% } + .news-container { width: 200px; padding-right: 8px } + .list-container { width: 578px; padding-right: 8px; padding-left: 0 } + .list-container h5 a { font-size: 12px; float: right } + .list-container .list-item { border: 1px solid #eee; padding: 8px } + .list-container .list-item:after { content: ''; display: block; clear: both; width: 100% } + .list-container .list-item label { display: block; width: 25%; float: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis } + .news-container .news-box { border: 1px solid #eee; padding: 8px } + .news-container .news-box hr { margin: 4px } + .news-container .news-box .news-item { position: relative; border: 1px solid #cecece; border-radius: 2px; overflow: hidden; cursor: pointer } + .news-container .news-box .news-image {background-position:center center;background-size:100%;height:90px} + .news-container .news-box .news-title { position: absolute; background: rgba(0, 0, 0, 0.5); color: #fff; padding: 2px; margin: 0; bottom: 0; left: 0; right: 0; text-align: right; white-space: nowrap; text-overflow: ellipsis; overflow: hidden } +</style> \ No newline at end of file