test_service d3170b4d1c 1
2023-12-01 15:43:29 +08:00

1 line
23 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\applet\controller;
use app\applet\model\Applet as AppletModel;
use app\applet\model\AppletName as AppletNameModel;
use app\applet\model\Wechat as WechatModel;
use app\applet\model\WechatBatchSend as WechatBatchSendModel;
use app\applet\model\Keyword as KeywordModel;
use app\applet\model\Setting as SettingModel;
use app\applet\model\User as UserModel;
use app\applet\model\UserDetail as UserDetailModel;
use app\applet\model\Apply as ApplyModel;
use hema\wechat\WxBizMsgCrypt;
use hema\wechat\Driver;
use think\facade\Cache;
/**
* 第三方平台与微信通讯接口
*/
class Task extends \app\BaseController
{
protected $wechat; //公众号
/**
* 支付宝异步消息
*/
public function alipay($msg_method='',$biz_content='')
{
ob_end_clean();
echo "success";
$data = json_decode($biz_content,true);
write_log($msg_method,__DIR__);
write_log($data,__DIR__);
//小程序审核通过通知
if($msg_method == 'alipay.open.mini.version.audit.passed')
{
write_log('小程序审核通过通知',__DIR__);
write_log($data,__DIR__);
}
//小程序审核不可营销通知
if($msg_method == 'alipay.open.mini.version.baseaudit.passed')
{
write_log('小程序审核不可营销通知',__DIR__);
write_log($data,__DIR__);
}
//小程序审核驳回通知
if($msg_method == 'alipay.open.mini.version.audit.rejected')
{
write_log('小程序审核驳回通知',__DIR__);
write_log($data,__DIR__);
}
//第三方应用授权取消消息
if($msg_method == 'alipay.open.auth.appauth.cancelled')
{
$model = new SettingModel;
$value = $model->where('key','alipay')
->where('values','like','%"app_auth_token":"'.$data['app_auth_token'].'"%')
->find();
if($value){
$arr = [];
foreach ($value['values'] as $key => $item){
$arr[$key] = '';
}
$model = new SettingModel;
$model->edit('alipay',$arr,$value['applet_id']);
}
}
die('success');
}
/**
* 微信授权事件接收通知处理
*/
public function wxopen()
{
// 接收公众号平台发送的消息
$msg_signature = empty ( $_GET['msg_signature'] ) ? '' : trim ( $_GET ['msg_signature'] );//签名
$timeStamp = empty ( $_GET ['timestamp']) ? '' : trim ( $_GET ['timestamp'] );//时间戳
$nonce = empty ( $_GET ['nonce'] ) ? '' : trim ( $_GET ['nonce'] );//随机数
$encryptMsg = file_get_contents ('php://input' );
$encrypt_type = empty ( $_GET['encrypt_type'] ) ? '' : trim ( $_GET ['encrypt_type'] );//加密类型,为 aes
$pc = new WxBizMsgCrypt();//创建解密类
$msg = '';
$errCode = $pc->decryptMsg($msg_signature, $timeStamp, $nonce, $encryptMsg, $msg);
if($errCode == 0){
$data = _xml_to_arr($msg); //XML转换为数组
//write_log($data, __DIR__);//用于测试callback.php接口
//推送的ticket
if($data['InfoType'] == 'component_verify_ticket'){
//更新过期的令牌component_access_token
if(!Cache::get('component_access_token_update')){
//过期更新access_token
$wx = new Driver;
if($result = $wx->getComponentToken($data['ComponentVerifyTicket'])){
// 缓存在3600秒之后过期
Cache::set('component_access_token',$result['component_access_token'], 7200);
Cache::set('component_access_token_update','update', 3600);
}else{
write_log($wx->getError(), __DIR__);
}
}
die('success');
}
//取消授权
if($data['InfoType'] == 'unauthorized'){
if($wechat = WechatModel::getWechat(['app_id' => $data['AuthorizerAppid']])){
$wechat->save([
'status' => 0,
'app_name' => '',
'head_img' => '',
'qrcode_url' => '',
'user_name' => '',
'app_id' => '',
'principal_name' => ''
]);
}
if($wxapp = AppletModel::getApplet(['app_id' => $data['AuthorizerAppid']])){
$wxapp->save([
'status' => 0,
'app_name' => '',
'head_img' => '',
'qrcode_url' => '',
'user_name' => '',
'app_id' => '',
'principal_name' => '',
'api_domain' => '',
'webview_domain' => '',
'signature' => ''
]);
}
die('success');
}
//更新授权
if($data['InfoType'] == 'updateauthorized'){
}
//成功授权
if($data['InfoType'] == 'authorized'){
}
//小程序注册成功
if($data['InfoType'] == 'notify_third_fasteregister'){
$this->fasteregister($data);//验证状态
die('success');
}
die('success');
}else{
//write_log('Callback 解密失败code'.$errCode, __DIR__);
}
}
/**
* 微信消息与事件接收通知处理
*/
public function wechat(string $appid = '')
{
if(!empty($appid)){
$this->wechat = WechatModel::getWechat(['app_id' => $appid]);
}
// 接收公众号平台发送的消息
$nonce = empty ( $_GET ['nonce'] ) ?"" : trim ( $_GET ['nonce'] );
$signature = empty ( $_GET['signature'] ) ? "" : trim ( $_GET ['signature'] );
$timeStamp = empty ( $_GET ['timestamp']) ? "" : trim ( $_GET ['timestamp'] );
$msg_signature = empty ( $_GET['msg_signature'] ) ? "" : trim ( $_GET ['msg_signature'] );
$encryptMsg = file_get_contents ('php://input' );
$pc = new WxBizMsgCrypt();//创建解密类
$msg = '';
$errCode = $pc->decryptMsg($msg_signature, $timeStamp, $nonce, $encryptMsg, $msg);
if($errCode == 0){
$data = _xml_to_arr($msg); //XML转换为数组
//write_log($data, __DIR__);
//*********************************接收事件推送*****************************************
if($data['MsgType']=='event'){
//用户未关注时,进行关注后的事件推送
if($data['Event']=='subscribe'){
$wx = new Driver;
if($wechat_user = $wx->getWechatUserInfo($data['FromUserName'],$this->wechat['applet_id'])){
//用户操作
$model = new UserModel;
if($user = $model->subscribe($wechat_user,$this->wechat['applet_id'])){
if($this->wechat['applet_id'] == 0){
$wx->sendServiceMsg([
'type' => 'text',
'content' => '请妥善保管您的账号和密码~账号:' . $user['user_name'] . ',密码:' .$user['password'] . ',如忘记回复“找回账号”找回~'
],$data['FromUserName'],$this->wechat['applet_id']);
}
}
if(isset($data['Ticket']) and $data['EventKey'] == 'qrscene_login'){
//扫码关注公众号
Cache::set($data['Ticket'],$wechat_user,3600);
}
}else{
//返回文本提醒
$wx->sendServiceMsg([
'type' => 'text',
'content' => $wx->getError()
],$data['FromUserName'],$this->wechat['applet_id']);
}
//是否设置了关注回复
if($subscribe = SettingModel::getItem('subscribe',$this->wechat['applet_id'])){
$this->replyMsg($subscribe,$data);//回复信息
}
die('success');
}
//用户已关注时扫码进入事件推送
if($data['Event']=='SCAN'){
if($this->wechat['applet_id'] == 0){
if(isset($data['Ticket']) and $data['EventKey'] == 'login'){
$wx = new Driver;
if($wechat_user = $wx->getWechatUserInfo($data['FromUserName'],$this->wechat['applet_id'])){
//扫码关注公众号
Cache::set($data['Ticket'],$wechat_user,3600);
}
}
}
die('success');
}
//取消关注事件
if($data['Event']=='unsubscribe'){
if($model = UserModel::getUser(['open_id' => $data['FromUserName']])){
$model->unSubscribe();
}
die('success');
}
//扫描带参数二维码事件 - 用户未关注时,进行关注后的事件推送
if($data['Event']=='subscribe' AND isset($data['EventKey'])){
die('success');
}
//扫描带参数二维码事件 - 用户已关注时的事件推送
if($data['Event']=='SCAN'){
die('success');
}
//上报地理位置事件
if($data['Event']=='LOCATION'){
die('success');
}
//自定义菜单事件 - 点击菜单拉取消息时的事件推送
if($data['Event']=='CLICK'){
//判断是否来自公众号菜单并携带关键字
if(isset($data['EventKey']) AND !empty($data['EventKey'])){
$data['Content'] = $data['EventKey'];
$data['MsgType'] = 'text';
$this->textMsg($data);
}
die('success');
}
//自定义菜单事件 - 点击菜单跳转链接时的事件推送
if($data['Event']=='VIEW'){
die('success');
}
//添加附近门店类目审核回调
if($data['Event']=='nearby_category_audit_info'){
//$this->nearby_category_audit_info($data);
die('success');
}
//添加附近小程序地点审核回调
if($data['Event']=='add_nearby_poi_audit_info'){
write_log('添加附近小程序地点审核回调',__DIR__);
die('success');
}
//群发任务回调事件推送
if($data['Event']=='MASSSENDJOBFINISH'){
$msg = WechatBatchSendModel::getSend($data['MsgID']);
$msg->backEdit($data);
die('success');
}
//代码审核成功结果推送
if($data['Event'] == 'weapp_audit_success'){
$values = SettingModel::getItem('ability',0);
//验证是否设置了自动上线
if($values['applet_online'] == 1){
//获取商户数据
if($applet = AppletModel::getApplet(['user_name' => $data['ToUserName']])){
$wx = new Driver;
$wx->release($applet['applet_id']);//发布已通过审核的小程序
}
}
die('success');
}
//代码审核失败结果推送
if($data['Event'] == 'weapp_audit_fail'){
die('success');
}
//代码审核延后推送
if($data['Event'] == 'weapp_audit_delay'){
die('success');
}
//名称审核结果事件推送
if($data['Event'] == 'wxa_nickname_audit'){
if($applet = AppletModel::getApplet([
'user_name' => $data['ToUserName']
])){
if($name = AppletNameModel::getAppletName(['nick_name' => $data['nickname'],'applet_id' => $applet['applet_id'],'status' => 0])){
//成功
if($data['ret']==3){
$name->save(['status' => 1]);
$applet->save(['app_name' => $data['nickname']]);
}
//失败
if($data['ret']==2){
$name->save(['status' => 2,'reason' => $data['reason']]);
$applet->save(['app_name' => $data['nickname'] . '->被拒绝:'.$data['reason']]);
}
}
}
die('success');
}
}
//*********************************接收普通消息*****************************************
//接收普通消息 - 文本消息
if($data['MsgType']=='text'){
$this->textMsg($data);//文本消息处理
die('success');
}
//接收普通消息 - 图片消息
if($data['MsgType']=='image'){
//发什么回什么
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => $data['MsgType'],
'MediaId' => $data['MediaId']
]);
die('success');
}
//接收普通消息 - 语音消息
if($data['MsgType']=='voice'){
//发什么回什么
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => $data['MsgType'],
'MediaId' => $data['MediaId']
]);
die('success');
}
//接收普通消息 - 视频消息
if($data['MsgType']=='video'){
//发什么回什么
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'text',
'Content' => '我不看,太低俗~'
]);
die('success');
}
//接收普通消息 - 小视频消息
if($data['MsgType']=='shortvideo'){
die('success');
}
//接收普通消息 - 地理位置消息
if($data['MsgType']=='location'){
die('success');
}
//接收普通消息 - 链接消息
if($data['MsgType']=='link'){
die('success');
}
die('success');
}else{
write_log('Wechat 解密失败 - 错误代码:'.$errCode, __DIR__);
}
}
/**
* 处理文本消息
*/
private function textMsg($data)
{
//是否设置了关键字回复
switch($data['Content']){
case 'id':
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'text',
'Content' => $data['FromUserName']
]);
break;
case '找回账号':
$this->getUserPassword($data);
break;
default:
if($values = KeywordModel::getKeys($data['Content'],$this->wechat['applet_id'])){
$this->replyMsg($values,$data);//回复信息
}else{
if($values = KeywordModel::getKeys('*',$this->wechat['applet_id'])){
$this->replyMsg($values,$data);//回复信息
}else{
//没有,发什么回什么
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => $data['MsgType'],
'Content' => $data['Content']
]);
}
}
}
}
/**
* 回复消息
*/
private function replyMsg($msg,$data)
{
//是否开启
if($msg['is_open']['value']==1){
//文字消息
if($msg['type']['value']=='text'){
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'text',
'Content' => $msg['content']['text']
]);
}
//图片消息
if($msg['type']['value']=='image'){
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'image',
'MediaId' => $msg['content']['media_id']
]);
}
//语音消息
if($msg['type']['value']=='voice'){
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'voice',
'MediaId' => $msg['content']['media_id']
]);
}
//视频消息
if($msg['type']['value']=='video'){
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'video',
'Title' => $msg['content']['title'],
'Description' => $msg['content']['description'],
'MediaId' => $msg['content']['media_id']
]);
}
/*
//音乐消息
if($msg['type']['value']=='music'){
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'music',
'Title' => $msg['content']['title'],
'Description' => $msg['content']['description'],
'MusicUrl' => $msg['content']['url'],
'HQMusicUrl' => $msg['content']['hurl'],
'ThumbMediaId' => $msg['content']['media_id']
]);
}*/
//图文消息
if($msg['type']['value']=='news'){
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'news',
'ArticleCount' => $msg['content']['article_count'],
'Articles' => $msg['content']['articles']
]);
}
}
}
/**
* 将array转为xml
*/
private function msgTpl($arr)
{
$xml ="<xml><ToUserName><![CDATA[" . $arr['ToUserName'] . "]]></ToUserName>";
$xml .="<FromUserName><![CDATA[" . $arr['FromUserName'] . "]]></FromUserName>";
$xml .="<CreateTime>" . time() . "</CreateTime>";
$xml .="<MsgType><![CDATA[" . $arr['MsgType'] . "]]></MsgType>";
switch($arr['MsgType']){
case "text":
$xml .="<Content><![CDATA[" . $arr['Content'] . "]]></Content>";
break;
case "image":
$xml .= "<Image><MediaId><![CDATA[" . $arr['MediaId'] . "]]></MediaId></Image>";
break;
case "voice":
$xml .= "<Voice><MediaId><![CDATA[" . $arr['MediaId'] . "]]></MediaId></Voice>";
break;
case "video":
$xml .= "<Video><MediaId><![CDATA[" . $arr['MediaId'] . "]]></MediaId><Title><![CDATA[" . $arr['Title'] . "]]></Title><Description><![CDATA[" . $arr['Description'] . "]]></Description></Video>";
break;
case "music":
$xml .= "<Music><Title><![CDATA[" . $arr['Title'] . "]]></Title><Description><![CDATA[" . $arr['Description'] . "]]></Description><MusicUrl><![CDATA[" . $arr['MusicUrl'] . "]]></MusicUrl><HQMusicUrl><![CDATA[" . $arr['HQMusicUrl'] . "]]></HQMusicUrl><ThumbMediaId><![CDATA[" . $arr['ThumbMediaId'] . "]]></ThumbMediaId></Music>";
break;
case "news":
$xml .= "<ArticleCount>".$arr['ArticleCount']."</ArticleCount><Articles>";
foreach ($arr['Articles'] as $vo){
$xml .= "<item><Title><![CDATA[". $vo['title'] ."]]></Title><Description><![CDATA[". $vo['description'] ."]]></Description><PicUrl><![CDATA[". $vo['pic_url'] ."]]></PicUrl><Url><![CDATA[". $vo['url'] ."]]></Url></item>";
}
$xml .= "</Articles>";
break;
}
$xml .= "</xml>";
return $xml;
}
/**
* 找回用户密码
*/
private function getUserPassword($data)
{
if($this->wechat['applet_id'] == 0){
//获取用户信息ID
if($model = UserModel::getUser(['open_id' => $data['FromUserName']])){
if($model->retrieve()){
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'text',
'Content' => '恭喜:成功找回账号~您的账号:' . $model['user_name'] . ',您的密码123456,提醒:每次找回都要重置密码~'
]);
}
}else{
//返回文本提醒
echo $this->msgTpl([
'ToUserName' => $data['FromUserName'],
'FromUserName' => $data['ToUserName'],
'MsgType' => 'text',
'Content' => '账号异常~请取消关注该公众号后,在重新关注后进行操作。'
]);
}
}
}
/**
* 快速注册小程序状态验证
*/
private function fasteregister(array $data)
{
//第一步、获取申请者资料
$detail = UserDetailModel::getDetail([
'merchant_name' => $data['info']['name'],
'license_number' => $data['info']['code'],
'legal_persona_wechat' => $data['info']['legal_persona_wechat'],
'id_card_name' => $data['info']['legal_persona_name']
]);
//第二步、获取到了资料
if($detail){
//第三步、查询申请记录
$apply = ApplyModel::where('apply_mode','<',30)->where([
'user_id' => $detail['user_id'],
'apply_status' => 20
])->order('apply_id','desc')->find();
//如果查询到了申请记录
if($apply){
//判断微信端审核状态
if($data['status'] == 0){
//审核成功 - 获取授权信息
$wx = new Driver;
if(!$auth = $wx->getAuth($data['auth_code'])){
return false;
}
//获取授权应用的帐号基本信息
if(!$result = $wx->getAppInfo($auth['authorizer_appid'])){
return false;
}
$app = $result['authorizer_info'];//得到授权应用的帐号基本信息
$api_domain = '';
$signature = '';
//添加服务器域名
if($result = $wx->setServeDomain(0,'',$auth['authorizer_access_token'])){
$api_domain = $result['apiurl'];
}
//设置小程序简介
if($result = $wx->setSignature(0,'',$auth['authorizer_access_token'])){
$signature = $result['signature'];
}
//更新小程序信息
$model = AppletModel::getApplet(['applet_id' => $apply['applet_id']]); //获取商户数据
$model->edit([
'user_name' => $app['user_name'], //原始ID
'principal_name' => $app['principal_name'], //主体名称
'app_id' => $auth['authorizer_appid'], //授权方APPid
'access_token' => $auth['authorizer_access_token'], //令牌
'expires_in' => time()+7000, //令牌过期时间
'authorizer_refresh_token' => $auth['authorizer_refresh_token'], //刷新令牌
'status' => 1, //是否授权
'source' => 20 //注册来源
]);
$title = '注册微信小程序';
$msg = '注册成功';
$apply->apply_status = 30;
}else{
//审核失败 (驳回操作)
$status = [
100001 => '已下发的模板消息法人并未确认且已超时24h未进行身份证校验',
100002 => '已下发的模板消息法人并未确认且已超时24h未进行人脸识别校验',
100003 => '已下发的模板消息法人并未确认且已超时24h',
101 => '工商数据返回:“企业已注销”',
102 => '工商数据返回:“企业不存在或企业信息未更新”',
103 => '工商数据返回:“企业法定代表人姓名不一致”',
104 => '工商数据返回:“企业法定代表人身份证号码不一致”',
105 => '法定代表人身份证号码,工商数据未更新,请 5-15 个工作日之后尝试',
1000 => '工商数据返回:“企业信息或法定代表人信息不一致”',
1001 => '主体创建小程序数量达到上限',
1002 => '主体违规命中黑名单',
1003 => '管理员绑定账号数量达到上限',
1004 => '管理员违规命中黑名单',
1005 => '管理员手机绑定账号数量达到上限',
1006 => '管理员手机号违规命中黑名单',
1007 => '管理员身份证创建账号数量达到上限',
1008 => '管理员身份证违规命中黑名单'
];
if($data['status'] == -1){
$apply->reject = '企业与法人姓名不一致';
}else{
if(isset($status[$data['status']])){
$apply->reject = $status[$data['status']];
}else{
$apply->reject = '未知原因';
}
}
$apply->apply_status = 40;
$title = '注册小程序 - 被驳回';
$msg = '注册失败';
}
}
//发送微信通知
sand_examine_msg($apply['apply_id'],$title,$msg,$apply['user_id']);
$apply->save();
}
return true;
}
}