2021年1月

不知道大家有没有这样的经历,换服务器的时候,网站的文件,数据库都得先备份,下载下来,然后再上传到新的服务器,重新进行配置,很是麻烦,所以不要轻易换服务器。今天在帮朋友迁移网站的时候,发现宝塔面板里面提供了迁移工具的宝塔一键迁移API版本。不知道为啥加API,反正就是好用就行了。下面小编说下使用方法以及注意事项:

环境准备:

两台服务器上都要安装宝塔面板,这个小编两个服务器的宝塔版本都是最新的(7.5.1)。还是建议大家升级到最新版本。
迁出的服务器: 安装宝塔一键迁移API版本,在软件商店里面安装就可以。(官方说:安装之前在首页点击一下修复)。
迁入的服务器: 只要保证面板版本必需>=6.9.5就可以了。

开始迁移

  • 迁入机器: 打开面本的API,点击面板设置-->API接口,获取接口API,并且吧迁出机器的ip放到白名单里面
    1.png
  • 迁出机器: 点击宝塔一键迁移API版本里面的设置,输入迁入机器的ip和刚刚获取的API。
    3.png
  • 检查环境,如果两个机器环境不一样,迁入机器缺什么都会提示的,按照提示装上就可以了。
    4.png
  • 选择要迁移的数据库,FTP,和网站就可以了。
    5.png
  • 接下来就是等待了
    6.png

注意: 迁出机器要留足够的空间,因为网站文件是要压缩的,不然没办法迁移。
努力

小编今天在使用npm install安装东西的时候出现了这样的错误

gyp: No Xcode or CLT version detected!
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:351:16)
gyp ERR! stack     at ChildProcess.emit (events.js:315:20)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:277:12)
gyp ERR! System Darwin 20.3.0
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/zero/projects/test/vue_test/big-screen-vue-datav/node_modules/fsevents
gyp ERR! node -v v14.16.0
gyp ERR! node-gyp -v v5.1.0
gyp ERR! not ok

看上面的提示可能是Xcode的问题,那么我们就重装下Xcode的吧,果然解决了问题。

xcode-select --install

ThinkPHP实现微信分享好友转发朋友圈自定义图片和文字的方法,在开始之前呢,我们需要准备好一些东西:

前期准备

  • 认证的公众号,订阅号或者服务号都可以,只要是认证过的就可以。
  • 公众号的AppID和AppSecret,登录微信公众平台,开发—基本配置,就可以看到啦。
  • 设置JSJS接口安全域名,登录微信公众平台,设置—公众号设置—功能设置里,填写就可以了。
  • 官方SDK,我们直接下载案例就可以,下载地址:http://demo.open.weixin.qq.com/jssdk/sample.zip里面包含php、java、nodejs以及python的示例代码。

服务端准备(ThinkPHP)

  • 将刚刚下载的jssdk.php文件重命名为Jssdk.php,然后和access_token.php、jsapi_ticket.php一起放入到ThinkPHP框架的第三方接口扩展目录下(extend/org/wechat/)。
  • 修改Jssdk.php文件

    1. 首先我们需要在构造函数中设置 $this->path = __DIR__ . DS; 即:

      namespace wechat;
      class Jssdk  {
       private $appId;
       private $appSecret;
       private $path;
       public function __construct($appId, $appSecret) {
       $this->appId = $appId;
       $this->appSecret = $appSecret;
       $this->path = __DIR__ . DS;
       }
       ...
      }
    2. get_php_file函数返回值中的$filename改为 $this->path.$filename ,即:

      private function get_php_file($filename) {
        return trim(substr(file_get_contents($this->path.$filename), 15));
      }
    3. 设置token的缓存,修改getAccessToken,加入cache

      private function getAccessToken() {
        // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
        // cache('at', ['access_token'=>'sss', 'expire_time' => '123']);
        // $data = json_decode($this->get_php_file("access_token.php"));
        $data = cache('at');
        if ($data['expire_time'] < time()) {
       // 如果是企业号用以下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->appId&secret=$this->appSecret";
       $res = json_decode($this->httpGet($url));
       $access_token = $res->access_token;
       if ($access_token) {
         // $data->expire_time = time() + 7000;
         // $data->access_token = $access_token;
         cache('at', ['access_token'=>$access_token, 'expire_time' => time() + 7000]);
         // $this->set_php_file("access_token.php", json_encode($data));
       }
        } else {
       $access_token = $data['access_token'];
        }
        return $access_token;
      }
  • 在控制器里面调用

    1. 导入jssdk, use wechat\Jssdk;
    2. 传给前端

      $jssdk = new Jssdk($AppID, $AppSecret);
      $res = $jssdk->getSignPackage();
      $appId = $res['appId'];
      $timestamp = $res['timestamp'];
      $nonceStr = $res['nonceStr'];
      $signature = $res['signature'];
      $this->assign(
       array(
           'appId'=>$appId,
           'timestamp'=>$timestamp,
           'nonceStr'=>$nonceStr,
           'signature'=>$signature,
       )
      );

      网页端

  • 导入jssdk

    <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
    
  • 设置分享内容

    <script type="text/javascript">
      var title = '分享标题';
      var imgUrl = '分享图片';
      var link = '分享地址';
      var desc = '分享描述';
     
      wx.config({
          debug: false,//开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
          appId: '{$appId}', // 必填,公众号的唯一标识
          timestamp: '{$timestamp}', // 必填,生成签名的时间戳
          nonceStr: '{$nonceStr}', //必填, 生成签名的随机串
          signature: '{$signature}', //必填,签名
          jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareQZone'] //必填, JS接口列表,这里只填写了分享需要的接口
      })
      wx.ready(function () {
          wx.onMenuShareTimeline({
              title: title,
              link: link,
              desc:desc,
              imgUrl: imgUrl,
              success: function() {
                  // 用户确认分享后执行的回调函数
              },
              cancel: function() {
                  // 用户取消分享后执行的回调函数
              }
          });
          wx.onMenuShareAppMessage({
              title: title, // 分享标题
              desc: desc, // 分享描述
              link: link, // 分享链接
              imgUrl: imgUrl, // 分享图标
              type: 'link', // 分享类型,music、video或link,不填默认为link
              dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
              success: function() {
                  // 用户确认分享后执行的回调函数
              },
              cancel: function() {
                  // 用户取消分享后执行的回调函数
              }
          });
      })
    </script>

做前端的小伙伴应该都很清楚使用vue的v-for就可以很方便的一个数组,然后对数组中的元素就行展示或者操作,那么有没有考虑过遍历对象呢。我们在学习js的时候都应该知道,我们使用js是可以遍历对象的,比如:

var oj = {"a":1, "b": 2, "c": 3}
for(var i in oj){
    console.log(i,"----->" ,oj[i])
}
// 输出
// a -----> 1
// b -----> 2
// c -----> 3

其实使用vue的v-for的效果是一样的,也是用的in。下面案例的输出结果是一样的:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <p v-for="(val, key, index) in list">{{key}}----->{{val}}</p>
    </div>

    <script>
        var obj=
        new Vue({
            el: '#app',
            data:{
                list:{
                    'a':1,
                    'b':2,
                    'c':3
                }
            }
        })
    </script>
</body>
</html>