由于微信公众号昵称头像授权政策调整,导致微擎打开应用页面跳转授权快照,获取不到用户真实的openid,造成无法支付,提示支付提示下单用户不一致。只需要把微擎默认的自动授权方式,改为引导用户手动点击授权就可以了。下面是修改的方式,需要修改到微擎源码。

1、新建一个手动授权的模板html文件,命名为auth.html,文件里的代码如下:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
  <title>授权登录-{$_W['account']['name']}</title>
  <meta name="keywords" content="{$_W['account']['name']}">
  <meta name="description" content="{$_W['account']['name']}">
  <style>
    .container {
      padding: 50px 15px;
      text-align: center;
    }
    .logo {
      width: 140px;
      margin: 0 auto 42px;
      text-align: center;
    }
    .logo img {
      max-width: 100%;
      vertical-align: middle;
    }
    .container h2 {
      margin: 0;
      padding: 0;
      line-height: 44px;
      font-size: 24px;
      font-weight: 500;
    }
    .container p {
      margin: 0;
      padding: 0;
      line-height: 34px;
      font-size: 16px;
    }
    .auth-btn {
      width: 98%;
      display: block;
      line-height: 50px;
      background: #0bb20c;
      color: #FFFFFF;
      text-align: center;
      font-size: 20px;
      border-radius: 24px;
      text-decoration: none;
      margin-top: 44px;
    }
    .is-snapshoot {
      display: none;
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      background-position: center;
      background-size: 100% 100%;
      z-index: 1;
      text-align: center;
    }
  </style>
</head>
<body>
<div class="container">
<!--  <div class="logo">-->
<!--    <img src="{$_W['account']['logo']}" alt="{$_W['account']['name']}">-->
<!--  </div>-->
  <h2>授权登录</h2>
  <p>为了提供更完善的服务,请先授权登录!</p>
  <div class="login-btn">
    <a class="auth-btn" href="{$forward}">点击授权登录</a>
  </div>
</div>
<div class="is-snapshoot" {if isset($_GPC['is_snapshotuser']) && $_GPC['is_snapshotuser']=='1' }style="display:block;" {/if}>请点击右下角【使用完整服务】</div>
</body>
</html>

创建文件后,把它放在目录/app/themes/default/auth/auth.html

2、修改 /app/common/bootstrap.app.inc.php文件,在这块代码大概171行下

if ($oauth_type == 'snsapi_base') {
        $forward = $oauth_account->getOauthCodeUrl($callback, $state);
} else {
    $forward = $oauth_account->getOauthUserInfoUrl($callback, $state);
}

新增如下代码:

template('auth/auth');
exit();

3、修改用户授权SESSION有效期。
/app/common/bootstrap.app.inc.php 文件里的
这段代码
WeSession::start($_W['uniacid'], CLIENT_IP);
替换成:
WeSession::start($_W['uniacid'], CLIENT_IP, (15 * 86400)); //15天有效期

4、在用户不授权的情况,再次进入系统,也会变成虚拟用户;修改文件:/app/source/auth/oauth.ctrl.php
在文件这段代码:

$oauth = $oauth_account->getOauthInfo($code);

下面大概30行新增如下代码:

if( isset($oauth['is_snapshotuser']) &&  intval($oauth['is_snapshotuser']) === 1){
    $_SESSION['oauth_openid'] = '';
    $backUrl = urldecode($_SESSION['dest_url']).'&is_snapshotuser=1'; //设置当前为快照模式,可以在授权页加个箭头引导右下角微信官方授权页面
    header('Location: ' . $backUrl);
    exit();
}

修改结束,最终效果是当用户访问应用的时候,就会先跳转到手动授权登录页面,点击授权按钮后,跳转到应用页面。

<bank_type><![CDATA[OTHERS]]></bank_type>
<cash_fee><![CDATA[1]]></cash_fee>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[N]]></is_subscribe>
<mch_id><![CDATA[1483469312]]></mch_id>
<nonce_str><![CDATA[8EYuWgYiwjnEhvOg]]></nonce_str>
<openid><![CDATA[oTgZpwaXTs2GzvkwMNDzbWIcrqjA]]></openid>
<out_trade_no><![CDATA[117120221215155347]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[18EE3825D2A3FD9A9DCBC60CAC131973]]></sign>
<time_end><![CDATA[20220514185750]]></time_end>
<total_fee>1</total_fee>
<trade_type><![CDATA[NATIVE]]></trade_type>
<transaction_id><![CDATA[4200001503202205144756789400]]></transaction_id>
</xml>

编译

set GOOS=linux

set GOARCH=amd64

go build -o "packageName"

发布

上传到服务器相关目录

chmod 777 main ------------修改权限

nohup ./main >log.txt --------后台运行程序

查看

查看运行进程pid: ps aux |grep main (main为名称)

服务器执行后台运行代码: nohup ./main &

关闭运行代码:kill -2 7159pid

ps -ef 可以查看所有进程

kill -pid 结束进程

比方说我通过查看进程发现上面运行的jar包的pid是21550,就可以这样结束它:

kill 21550

package tools

import (
    "math"
)

// WGS84坐标系:即地球坐标系,国际上通用的坐标系。
// GCJ02坐标系:即火星坐标系,WGS84坐标系经加密后的坐标系。Google Maps,高德在用。
// BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系。

const (
    X_PI   = math.Pi * 3000.0 / 180.0
    OFFSET = 0.00669342162296594323
    AXIS   = 6378245.0
)

//BD09toGCJ02 百度坐标系->火星坐标系
func BD09toGCJ02(lon, lat float64) (float64, float64) {
    x := lon - 0.0065
    y := lat - 0.006

    z := math.Sqrt(x*x+y*y) - 0.00002*math.Sin(y*X_PI)
    theta := math.Atan2(y, x) - 0.000003*math.Cos(x*X_PI)

    gLon := z * math.Cos(theta)
    gLat := z * math.Sin(theta)

    return gLon, gLat
}

//GCJ02toBD09 火星坐标系->百度坐标系
func GCJ02toBD09(lon, lat float64) (float64, float64) {
    z := math.Sqrt(lon*lon+lat*lat) + 0.00002*math.Sin(lat*X_PI)
    theta := math.Atan2(lat, lon) + 0.000003*math.Cos(lon*X_PI)

    bdLon := z*math.Cos(theta) + 0.0065
    bdLat := z*math.Sin(theta) + 0.006

    return bdLon, bdLat
}

//WGS84toGCJ02 WGS84坐标系->火星坐标系
func WGS84toGCJ02(lon, lat float64) (float64, float64) {
    if isOutOFChina(lon, lat) {
        return lon, lat
    }

    mgLon, mgLat := delta(lon, lat)

    return mgLon, mgLat
}

//GCJ02toWGS84 火星坐标系->WGS84坐标系
func GCJ02toWGS84(lon, lat float64) (float64, float64) {
    if isOutOFChina(lon, lat) {
        return lon, lat
    }

    mgLon, mgLat := delta(lon, lat)

    return lon*2 - mgLon, lat*2 - mgLat
}

//BD09toWGS84 百度坐标系->WGS84坐标系
func BD09toWGS84(lon, lat float64) (float64, float64) {
    lon, lat = BD09toGCJ02(lon, lat)
    return GCJ02toWGS84(lon, lat)
}

//WGS84toBD09 WGS84坐标系->百度坐标系
func WGS84toBD09(lon, lat float64) (float64, float64) {
    lon, lat = WGS84toGCJ02(lon, lat)
    return GCJ02toBD09(lon, lat)
}

func delta(lon, lat float64) (float64, float64) {
    dlat := transformlat(lon-105.0, lat-35.0)
    dlon := transformlng(lon-105.0, lat-35.0)

    radlat := lat / 180.0 * math.Pi
    magic := math.Sin(radlat)
    magic = 1 - OFFSET*magic*magic
    sqrtmagic := math.Sqrt(magic)

    dlat = (dlat * 180.0) / ((AXIS * (1 - OFFSET)) / (magic * sqrtmagic) * math.Pi)
    dlon = (dlon * 180.0) / (AXIS / sqrtmagic * math.Cos(radlat) * math.Pi)

    mgLat := lat + dlat
    mgLon := lon + dlon

    return mgLon, mgLat
}

func transformlat(lon, lat float64) float64 {
    var ret = -100.0 + 2.0*lon + 3.0*lat + 0.2*lat*lat + 0.1*lon*lat + 0.2*math.Sqrt(math.Abs(lon))
    ret += (20.0*math.Sin(6.0*lon*math.Pi) + 20.0*math.Sin(2.0*lon*math.Pi)) * 2.0 / 3.0
    ret += (20.0*math.Sin(lat*math.Pi) + 40.0*math.Sin(lat/3.0*math.Pi)) * 2.0 / 3.0
    ret += (160.0*math.Sin(lat/12.0*math.Pi) + 320*math.Sin(lat*math.Pi/30.0)) * 2.0 / 3.0
    return ret
}

func transformlng(lon, lat float64) float64 {
    var ret = 300.0 + lon + 2.0*lat + 0.1*lon*lon + 0.1*lon*lat + 0.1*math.Sqrt(math.Abs(lon))
    ret += (20.0*math.Sin(6.0*lon*math.Pi) + 20.0*math.Sin(2.0*lon*math.Pi)) * 2.0 / 3.0
    ret += (20.0*math.Sin(lon*math.Pi) + 40.0*math.Sin(lon/3.0*math.Pi)) * 2.0 / 3.0
    ret += (150.0*math.Sin(lon/12.0*math.Pi) + 300.0*math.Sin(lon/30.0*math.Pi)) * 2.0 / 3.0
    return ret
}

func isOutOFChina(lon, lat float64) bool {
    return !(lon > 73.66 && lon < 135.05 && lat > 3.86 && lat < 53.55)
}

/**
     * 判断一个坐标是否在圆内
     * 思路:判断此点的经纬度到圆心的距离  然后和半径做比较
     * 如果此点刚好在圆上 则返回true
     * @param $point ['lng'=>'','lat'=>''] array指定点的坐标
     * @param $circle array ['center'=>['lng'=>'','lat'=>''],'radius'=>'']  中心点和半径
     */
    function is_point_in_circle($point, $circle){
 
        $distance = $this -> distance($point['lat'],$point['lng'],$circle['center']['lat'],$circle['center']['lng']);
        if($distance <= $circle['radius']){
            return true;
        }else{
            return false;
        }
    }



/**
     * 判断一个坐标是否在一个多边形内(由多个坐标围成的)
     * 基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
     * 在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。
     * @param $point 指定点坐标
     * @param $pts 多边形坐标 顺时针方向
     */
    function is_point_in_polygon($point, $pts) {
        $N = count($pts);
        $boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
        $intersectCount = 0;//cross points count of x
        $precision = 2e-10; //浮点类型计算时候与0比较时候的容差
        $p1 = 0;//neighbour bound vertices
        $p2 = 0;
        $p = $point; //测试点
 
        $p1 = $pts[0];//left vertex
        for ($i = 1; $i <= $N; ++$i) {//check all rays
            // dump($p1);
            if ($p['lng'] == $p1['lng'] && $p['lat'] == $p1['lat']) {
                return $boundOrVertex;//p is an vertex
            }
 
            $p2 = $pts[$i % $N];//right vertex
            if ($p['lat'] < min($p1['lat'], $p2['lat']) || $p['lat'] > max($p1['lat'], $p2['lat'])) {//ray is outside of our interests
                $p1 = $p2;
                continue;//next ray left point
            }
 
            if ($p['lat'] > min($p1['lat'], $p2['lat']) && $p['lat'] < max($p1['lat'], $p2['lat'])) {//ray is crossing over by the algorithm (common part of)
                if($p['lng'] <= max($p1['lng'], $p2['lng'])){//x is before of ray
                    if ($p1['lat'] == $p2['lat'] && $p['lng'] >= min($p1['lng'], $p2['lng'])) {//overlies on a horizontal ray
                        return $boundOrVertex;
                    }
 
                    if ($p1['lng'] == $p2['lng']) {//ray is vertical
                        if ($p1['lng'] == $p['lng']) {//overlies on a vertical ray
                            return $boundOrVertex;
                        } else {//before ray
                            ++$intersectCount;
                        }
                    } else {//cross point on the left side
                        $xinters = ($p['lat'] - $p1['lat']) * ($p2['lng'] - $p1['lng']) / ($p2['lat'] - $p1['lat']) + $p1['lng'];//cross point of lng
                        if (abs($p['lng'] - $xinters) < $precision) {//overlies on a ray
                            return $boundOrVertex;
                        }
 
                        if ($p['lng'] < $xinters) {//before ray
                            ++$intersectCount;
                        }
                    }
                }
            } else {//special case when ray is crossing through the vertex
                if ($p['lat'] == $p2['lat'] && $p['lng'] <= $p2['lng']) {//p crossing over p2
                    $p3 = $pts[($i+1) % $N]; //next vertex
                    if ($p['lat'] >= min($p1['lat'], $p3['lat']) && $p['lat'] <= max($p1['lat'], $p3['lat'])) { //p.lat lies between p1.lat & p3.lat
                        ++$intersectCount;
                    } else {
                        $intersectCount += 2;
                    }
                }
            }
            $p1 = $p2;//next ray left point
        }
 
        if ($intersectCount % 2 == 0) {//偶数在多边形外
            return false;
        } else { //奇数在多边形内
            return true;
        }
    }

测试代码:

?php
$point = ['lng'=>116.394299,'lat'=>40.011674];
$circle = [
    'center'=>['lng'=>116.12637,'lat'=>40.114308],
    'radius'=>46807.83038795571
];
 
$convert = new Convert();
$bool = $convert -> is_point_in_circle($point,$circle);
//var_dump($bool);
 
$pts = [
    ['lng'=>115.934109, 'lat'=>40.124809],
    ['lng'=>116.554836, 'lat'=>40.177293],
    ['lng'=>116.620754, 'lat'=>39.783734],
    ['lng'=>116.054958, 'lat'=>39.809057]
];
 
$point = ['lng'=>115.989864,'lat'=>39.973272];
$bool = $convert -> is_point_in_polygon($point,$pts);
var_dump($bool);