微信分享想要有小卡片样式,必须走公众号进去的H5才有,朋友圈也一样,类似下图
后台接口使用得 eeasywechat-4.x
WeChatServer.php
/**
* 公众号配置
* @var array
*/
public function __construct()
{
$this->config = [
'app_id' => Env::get('wechat.app_id'),
'secret' => Env::get('wechat.secret'),
'token' => Env::get('wechat.token'),
'aes_key' => Env::get('wechat.aes_key'),
'mch_id' => Env::get('wechat_mch.mch_id'),
'key' => Env::get('wechat_mch.key'),
// 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
// EXTEND_PATH 默认为 extend 目录
'cert_path' => EXTEND_PATH.'/zcerts/apiclient_cert.pem', // XXX: 绝对路径!!!!
'key_path' => EXTEND_PATH.'/zcerts/apiclient_key.pem', // XXX: 绝对路径!!!!
'notify_url' => '', // 你也可以在下单时单独设置来覆盖它
// 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
'response_type' => 'collection',
'oauth' => [
'scopes' => ['snsapi_userinfo'],
'callback' => '',
],
'log' => [
'level' => 'debug',
'file' => __DIR__ . '/wechat-log',
],
];
}
// easywechat
public function getJsapi($url){
$app = Factory::officialAccount($this->config);
$menu = array(
'checkJsApi',
'updateAppMessageShareData',
'updateTimelineShareData',
);
$app->jssdk->setUrl($url);
$jssdk = $app->jssdk->buildConfig($menu, false, false, false);
return $jssdk;
}
// 微信官方demo
public function getSignedPackage($url)
{
$jsapiTicket = $this->getJsApiTicket();
$timestamp = time();
$nonceStr = Random::alnum(16);
// 这里参数的顺序要按照 key 值 ASCII 码升序排序
$string = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}×tamp={$timestamp}&url={$url}";
$signature = sha1($string);
$signPackage = array(
"appId" => $this->config['app_id'],
"nonceStr" => $nonceStr,
"timestamp" => $timestamp,
"url" => $url,
"signature" => $signature,
"rawString" => $string,
"jsticket" => $jsapiTicket,
);
return $signPackage;
}
private function getJsApiTicket()
{
$ticket = Cache::get("wechat_jsapi_ticket");
if (!$ticket) {
$accessToken = $this->getAccessToken();
// 如果是企业号用以下 URL 获取 ticket
// $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token={$accessToken}";
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token={$accessToken}";
$ret = Http::get($url);
$json = json_decode($ret, true);
$ticket = isset($json['ticket']) ? $json['ticket'] : '';
if ($ticket) {
Cache::set('wechat_jsapi_ticket', $ticket, 7200);
}
}
return $ticket;
}
private function getAccessToken()
{
$token = Cache::get("wechat_access_token");
if (!$token) {
// 如果是企业号用以下URL获取access_token
// $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$this->appId}&corpsecret={$this->appSecret}";
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->config['app_id']}&secret={$this->config['secret']}";
$ret = Http::get($url);
$json = json_decode($ret, true);
$token = isset($json['access_token']) ? $json['access_token'] : '';
if ($token) {
Cache::set('wechat_access_token', $token, 7200);
}
}
return $token;
}
api.php
public function WechatShare(){
$data = $this->request->post();
$type = $this->request->post('type');
$request = Request::instance();
$domain = $request->domain();
if ($type){
if($type == 'list'){
$res['single'] = pemodel::where('id',$data['dataid'])->field('name,description')->find();
$jssdk = new WeChatServer();
// 重点,解码前台传递url
$dcurl = urldecode($data['url']);
// 两个方法都可以
// $res['package'] = $jssdk->getSignedPackage($dcurl);
// easywechat
$res['package'] = $jssdk->getJsapi($dcurl);
if ($res['package']){
// $res['url']
$res['url'] = $dcurl;
$this->success('请求成功',$res,200);
return;
}
$this->error('请求失败',$res['package'],201);
}
}
$this->error('参数错误',$type,201);
}
前台
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js" type="text/javascript" charset="utf-8"></script>
<script>
// 把当前url编码传递到后台
let url = encodeURIComponent(window.location.href.split('#')[0]);
$(".div-wechat-share").click(function (){
const me = $(this);
const dataid = me.attr("data-id");
$.ajax({
url:"/api/page/WechatShare",
type:"post",
data:{
dataid,
type:"list",
url,
},
success:function (res, ret){
try {
wx.config({
debug:false,
appId: res.data.package.appId,
timestamp: res.data.package.timestamp,
nonceStr: res.data.package.nonceStr,
signature: res.data.package.signature,
jsApiList: [
"checkJsApi",
"updateAppMessageShareData", // 分享给好友
"updateTimelineShareData", // 分享到朋友圈
]
});
wx.checkJsApi({
jsApiList: [
"checkJsApi",
"updateAppMessageShareData", // 分享给好友
"updateTimelineShareData", // 分享到朋友圈
], // 需要检测的 JS 接口列表,所有 JS 接口列表见附录2,
success: function(res) {
// 以键值对的形式返回,可用的 api 值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
console.log("checkJsApi",res);
}
});
wx.ready(function(){
// config信息验证后会执行 ready 方法,所有接口调用都必须在 config 接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在 ready 函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在 ready 函数中。
// 分享给朋友
wx.updateAppMessageShareData({
title: "aa中医视频", // 分享标题
desc: "aa中医视频描述", // 分享描述
link: res.data.url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
imgUrl: "https://rbm.ystzyyy.com/assets/yst/8af088e58d20fb41ada08295e906a70.jpg", // 分享图标
success: function (e) {
// 设置成功
console.log("分享朋友成功",e);
}
});
// 分享到朋友圈
wx.updateTimelineShareData({
title: "bb推荐中医视频", // 分享标题
link: res.data.url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
imgUrl: "https://rbm.ystzyyy.com/assets/yst/8af088e58d20fb41ada08295e906a70.jpg", // 分享图标
success: function (e) {
// 设置成功
console.log("分享圈成功",e);
}
})
});
} catch (e) {
console.log("分享失败返回错误",e);
}
return false;
}
});
});
</script>
重点:微信分享想要有小卡片样式,必须走公众号进去的H5才有,或者走公众号菜单进去,再跳转都可以,必须走公众号