和蕙健康小程序后端
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.

241 lines
8.1 KiB

9 months ago
<?php
namespace addons\shopro\controller\wechat;
use addons\shopro\facade\Wechat;
use app\admin\model\shopro\wechat\Reply;
use app\admin\model\shopro\wechat\Material;
use EasyWeChat\Kernel\Messages\Image;
use EasyWeChat\Kernel\Messages\Media;
use EasyWeChat\Kernel\Messages\Text;
use EasyWeChat\Kernel\Messages\News;
use EasyWeChat\Kernel\Messages\NewsItem;
use EasyWeChat\Kernel\Messages\Video;
use EasyWeChat\Kernel\Messages\Voice;
use app\admin\model\shopro\ThirdOauth;
class Serve
{
protected $noNeedLogin = ['*'];
protected $noNeedRight = ['*'];
protected $wechat = null;
protected $openid = "";
// 微信api
public function index()
{
$this->wechat = Wechat::officialAccountManage();
$this->wechat->server->push(function ($message) {
$this->openid = $message['FromUserName'];
return $this->reply($message);
});
$this->wechat->server->serve()->send();
}
// 回复消息
private function reply($message)
{
switch ($message['MsgType']) {
// 收到事件
case 'event':
switch ($message['Event']) {
// 订阅(关注)事件
case 'subscribe':
$data = ['openid' => $this->openid];
\think\Hook::listen('wechat_subscribe', $data);
$reply = Reply::where('group', 'subscribe')->enable()->find();
if ($reply) {
$this->getReplyData($reply);
}
if (!empty($message['EventKey'])) {
$event = str_replace('qrscene_', '', $message['EventKey']);
return $this->scanQrcode($event);
}
break;
// 取消订阅(关注)事件
case 'unsubscribe':
$data = ['openid' => $this->openid];
\think\Hook::listen('wechat_unsubscribe', $data);
break;
//自定义菜单事件
case 'CLICK':
$event = explode('|', $message['EventKey']);
return $this->getClickData($event);
break;
case 'SCAN':
if (!empty($event = $message['EventKey'])) {
return $this->scanQrcode($event);
}
break;
}
break;
// 收到文本消息
case 'text':
//检测关键字回复
$keywords = $message['Content'];
$reply = Reply::where('group', 'keywords')->enable()->where('find_in_set(:keywords, keywords)', ['keywords' => $keywords])->find();
if ($reply) {
return $this->getReplyData($reply);
}
break;
// 收到图片消息 暂不支持此消息类型
case 'image':
// 收到语音消息 暂不支持此消息类型
case 'voice':
// 收到视频消息 暂不支持此消息类型
case 'video':
// 收到坐标消息 暂不支持此消息类型
case 'location':
// 收到链接消息 暂不支持此消息类型
case 'link':
// 收到文件消息 暂不支持此消息类型
case 'file':
// 默认回复消息
default:
$reply = Reply::where('group', 'default')->enable()->find();
if ($reply) {
return $this->getReplyData($reply);
}
}
return true;
}
// 组装回复消息的数据结构
private function getReplyData($reply)
{
switch ($reply->type) {
// 回复文本消息
case 'text':
$material = Material::find($reply->content);
if ($material) {
$data = new Text($material->content);
}
break;
// 回复链接卡片
case 'link':
$material = Material::find($reply->content);
if ($material) {
$link = $material->content;
$items = new NewsItem([
'title' => $link['title'],
'description' => $link['description'],
'url' => $link['url'],
'image' => cdnurl($link['image'], true),
]);
$data = new News([$items]);
}
break;
case 'video':
$data = new Video($reply->content);
break;
case 'voice':
$data = new Voice($reply->content);
break;
case 'image':
$data = new Image($reply->content);
break;
case 'news':
$data = new Media($reply->content, 'mpnews');
break;
}
// 使用客服消息发送
$this->wechat->customer_service->message($data)->to($this->openid)->send();
}
// 组装事件消息的数据结构
private function getClickData($event)
{
switch ($event[0]) {
// 回复文本消息
case 'text':
$material = Material::find($event[1]);
if ($material) {
$data = new Text($material->content);
}
break;
// 回复链接卡片
case 'link':
$material = Material::find($event[1]);
if ($material) {
$link = $material->content;
$items = new NewsItem([
'title' => $link['title'],
'description' => $link['description'],
'url' => $link['url'],
'image' => cdnurl($link['image'], true),
]);
$data = new News([$items]);
}
break;
case 'video':
$data = new Video($event[1]);
break;
case 'voice':
$data = new Voice($event[1]);
break;
case 'image':
$data = new Image($event[1]);
break;
case 'news':
$data = new Media($event[1], 'mpnews');
break;
}
// 使用客服消息发送
$this->wechat->customer_service->message($data)->to($this->openid)->send();
}
// 扫一扫微信二维码
private function scanQrcode($eventStr)
{
list($flag, $event, $eventId) = explode('.', $eventStr);
$text = '';
if (empty($flag) || empty($event)) {
$text = '未找到对应扫码事件';
} else {
switch ($event) {
case 'login':
// $text = $this->login($eventId);
break;
case 'bind':
$text = $this->bind($eventId);
break;
}
}
if (!empty($text)) {
$this->wechat->customer_service->message(new Text($text))->to($this->openid)->send();
}
return;
}
// 扫一扫绑定管理员
private function bind($eventId)
{
$cacheKey = "wechatAdmin.bind.{$eventId}";
$cacheValue = cache($cacheKey);
if (empty($cacheValue)) {
return '二维码已过期,请重新扫码';
}
$thirdOauth = ThirdOauth::where([
'provider' => 'wechat',
'platform' => 'admin',
'openid' => $this->openid
])->find();
if ($thirdOauth && $thirdOauth->admin_id !== 0) {
return '该微信账号已绑定其他管理员';
}
cache($cacheKey, ['id' => $this->openid], 1 * 60);
return '正在绑定管理员快捷登录';
}
}