分类目录归档:编程

微信小程序之上传图片(含前后端代码例子)

前端小程序代码

index.wxml:

<view class='content'>
  <view class='img-box'>
    <view class='img-list'>
      <block wx:for="{{detailPics}}" wx:key="index">
        <view class='img-item'>
          <image src='{{item}}' bindlongpress="bindlongpressimg" data-id='{{index}}'></image>
        </view>
      </block>
      <view class='chooseimg' bindtap='uploadDetailImage'>
        <view class="weui-uploader__input-box"></view>
      </view>
    </view>
    <view class='tips'>长按对应的图片即可删除</view>
  </view>
</view>

index.js:

// component/uploadImages/index.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    count: { //最多选择图片的张数,默认9张
      type: Number,
      value: 9
    },
    uploadUrl: { //图片上传的服务器路径
      type: String,
      value: ''
    },
    showUrl: { //图片的拼接路径
      type: String,
      value: ''
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    detailPics: [], //上传的结果图片集合
  },

  ready: function () {
    console.log(this.data)
  },

  /**
   * 组件的方法列表
   */
  methods: {

    uploadDetailImage: function (e) { //这里是选取图片的方法
      var that = this;
      var pics = [];
      var detailPics = that.data.detailPics;
      if (detailPics.length >= that.data.count) {
        wx.showToast({
          title: '最多选择' + that.data.count + '张!',
        })
        return;
      }
      wx.chooseImage({
        count: that.data.count, // 最多可以选择的图片张数,默认9
        sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认二者都有
        sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
        success: function (res) {
          var imgs = res.tempFilePaths;
          for (var i = 0; i < imgs.length; i++) {
            pics.push(imgs[i])
          }
          that.uploadimg({
            url: "http://www.test.com//test-api/wechat/applet/api/uploadUserAvatar", //这里是你图片上传的接口
            path: pics, //这里是选取的图片的地址数组
          });
        },
      })

    },
    //多张图片上传
    uploadimg: function (data) {
      wx.showLoading({
        title: '上传中...',
        mask: true,
      })
      var that = this,
        i = data.i ? data.i : 0,
        success = data.success ? data.success : 0,
        fail = data.fail ? data.fail : 0;
      wx.uploadFile({
        url: data.url,
        filePath: data.path[i],
        name: 'file',
        formData: {"userId":"35"},
        success: (resp) => {
          wx.hideLoading();
          success++;
          var str = resp.data //返回的结果,可能不同项目结果不一样

          console.log(str);
          // var pic = JSON.parse(str);
          // var pic_name = that.data.showUrl + pic.Data;
          // var detailPics = that.data.detailPics;
          // detailPics.push(pic_name)
          // that.setData({
          //   detailPics: detailPics
          // })
        },
        fail: (res) => {
          fail++;
          console.log('fail:' + i + "fail:" + fail);
        },
        complete: () => {
          i++;
          if (i == data.path.length) { //当图片传完时,停止调用     
            console.log('执行完毕');
            console.log('成功:' + success + " 失败:" + fail);
            var myEventDetail = {
              picsList: that.data.detailPics
            } // detail对象,提供给事件监听函数
            var myEventOption = {} // 触发事件的选项
            that.triggerEvent('myevent', myEventDetail, myEventOption)//结果返回调用的页面
          } else { //若图片还没有传完,则继续调用函数
            data.i = i;
            data.success = success;
            data.fail = fail;
            that.uploadimg(data);//递归,回调自己
          }
        }
      });
    },

  }
})

后端Java代码(这里我使用的是第三方存储,如腾讯云,如果读者朋友们是使用第三方存储替换是一件很容易的事情)

核心代码如下:

@PostMapping("/uploadUserAvatar")
@ApiOperation(value = "上传用户头像", notes = "上传用户头像")
public JSONObject uploadUserAvatar(HttpServletRequest request) {

    JSONObject json = new JSONObject();
    try {

        String userId = request.getParameter("userId");

        COSClientUtil cosClientUtil = new COSClientUtil();

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;

        // 获取上传的文件
        MultipartFile multiFile = multipartRequest.getFile("file");

        
        
        String name = cosClientUtil.uploadFileCos(multiFile);

        // 获取文件路径
        String fileUrl = cosClientUtil.getFileUrl(name);
        
        Console.log("fileUrl:"+fileUrl);
        
        
        // 对文件路径进行处理
        String dbFileUrl = fileUrl.substring(0, fileUrl.indexOf("?"));
        
        
        Console.log("dbFileUrl:"+dbFileUrl);

        User user = new User();
        user.setId(Integer.parseInt(userId));
        user.setSmallAvatar(dbFileUrl);

        boolean isUploadUserAvatar = userService.updateById(user);

        if (isUploadUserAvatar) {
            json.put(ResponseUtils.CODE, ResponseUtils.SUCCESS_CODE);
            json.put(ResponseUtils.MSG, ResponseUtils.SUCCEESS_MSG);
        } else {
            json.put(ResponseUtils.CODE, ResponseUtils.ERROR_CODE);
            json.put(ResponseUtils.MSG, ResponseUtils.ERROR_MSG);
        }

    } catch (Exception e) {
        e.printStackTrace();

        json.put(ResponseUtils.CODE, ResponseUtils.ERROR_CODE);
        json.put(ResponseUtils.MSG, ResponseUtils.ERROR_MSG);

    }

    return json;
}

原文:https://www.cnblogs.com/youcong/p/11524006.html

微信小程序 点击复制文本到剪贴板

调用小程序的接口来实现,没什么难点,就直接上代码啦。

wxml:

<view>内容:{{contents}} </view>
<view  bindtap='copyText' data-text="{{contents}}">复制</view>

js:

Page({
  data: {
    contents:'这是可以复制的文字,粘贴后即可看到效果'
  },
  copyText: function (e) {
    console.log(e)
    wx.setClipboardData({
      data: e.currentTarget.dataset.text,
      success: function (res) {
        wx.getClipboardData({
          success: function (res) {
            wx.showToast({
              title: '复制成功'
            })
          }
        })
      }
    })
  },
}

JS字符串和数组之间的转换

1、字符串转换为数组
var string = '123,456,789';
var stringResult = string.split(',');
console.log(stringResult) //输出["123", "456", "789"]
 
var string2 = 'abcdef'
var string2Result = string2.split('')
console.log(string2Result) //输出['a','b','c','d','e','f']
string2.split(",").map(Number);//输出[123,456,789]
JSON.parse("[" + string + "]"); //输出[123,456,789]
 
2、数组转换为字符串
var array = ['abc', 'def', 'hig']
var arrayResult = array.join(',')
console.log(arrayResult) // 输出"abc,def,hig"
array.toString()//输出"abc,def,hig"

微信小程序实现下拉刷新

  • 本文将简单介绍如何实现微信小程序的下拉刷新
  • 将要使用的api:
    1. wx.showNavigationBarLoading(Object object)
    2. wx.showLoading(Object object)
    3. wx.hideLoading(Object object)
    4. wx.hideNavigationBarLoading(Object object)
    5. wx.stopPullDownRefresh(Object object)
    6. wx.request(Object object)
    //刷新
    onRefresh(){
        //在当前页面显示导航条加载动画
        wx.showNavigationBarLoading(); 
        //显示 loading 提示框。需主动调用 wx.hideLoading 才能关闭提示框
        wx.showLoading({
          title: '刷新中...',
        })
        this.getData();
      },
    //网络请求,获取数据
    getData(){
    	wx.request({
            url: '',
            //网络请求执行完后将执行的动作
            complete(res){
                //隐藏loading 提示框
                wx.hideLoading();
                //隐藏导航条加载动画
                wx.hideNavigationBarLoading();
                //停止下拉刷新
                wx.stopPullDownRefresh();
      	  	}
    	})   
    },
    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: function () {
        //调用刷新时将执行的方法
    	this.onRefresh();
    }

除了在js页面编写响应的逻辑之外,还需要再相应页面的json中写入以下配置,这个配置允许这个页面进行下拉刷新动作

    {
         "enablePullDownRefresh": true
    }

特别需要注意的是:

  • 写之前先看看有无已经存在的onPullDownRefresh:function()函数,否则将不能监听到用户的下拉刷新动作
  • 注意相关api的配对使用
  • 不要忘了在需要刷新结束时调用wx.stopPullDownRefresh(),否则,页面将会保持下拉状态、不会回弹。·

此外,除了下拉刷新,有时候可能是在某个事件进行时触发刷新动作,此时可以调用wx.startPullDownRefresh(Object object) 此api的作用是:“ 开始下拉刷新。调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。”

原文:https://www.cnblogs.com/xunxian/p/12862660.html

js过滤emoji表情符号

手机端常常会遇到用户输入框,输入emoji,如果是数据库是UTF8,会遇到报错:SQLException: Incorrect string value: ‘\xF0\x9F\x98\x84’ for column ‘review’ at row 1

原因是:UTF-8编码有可能是两个、三个、四个字节。Emoji表情是4个字节,而Mysql的utf8编码最多3个字节,所以数据插不进去。

过滤

php过滤emoji表情:

$name = preg_replace('/[^\\u0000-\\uFFFF]/ig', '', $string);

js过滤emoji表情:

name = name.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "");

原文:https://blog.csdn.net/ugg/article/details/44225723

php 根据实际地址获取对应的经纬度

在php中根据实际地址获取对应的经纬度,这里推荐使用百度地图和腾讯地图提供的现成的接口

这里注意一点:

百度地图和腾讯地图的坐标与真实经纬度是不同的,国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密,腾讯使用的就是国测局制定的GCJ-02。百度坐标在此基础上,进行了BD-09二次加密措施

一:百度地图:

根据实际地址获取经纬度的百度接口文档地址:地理编码

1:获取密钥

点击文档左侧的获取密钥按钮,根据提示获取密钥

image.png

2:实现根据实际地址获取到经纬度

<?php
function curl($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    //参数为1表示传输数据,为0表示直接输出显示。
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    //参数为0表示不带头文件,为1表示带头文件
    curl_setopt($ch, CURLOPT_HEADER,0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,false);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}
$data_info=curl("http://api.map.baidu.com/geocoder/v2/?address=实际地址&output=json&ak=你的密钥");
$data_info = json_decode($data_info, true); //数据转换
print_r($data_info);

根据如上的代码就可以获取到实际地址对应的经纬度

二:腾讯地图

腾讯根据实际地址获取经纬度接口文档:https://lbs.qq.com/webservice_v1/guide-geocoder.html

1:获取密钥:

申请密钥地址:https://lbs.qq.com/console/key.html

根据提示获取到所需的密钥

2:获取实际地址的经纬度

接口:https://apis.map.qq.com/ws/geocoder/v1/?address=实际地址&key=您的密钥

代码实现和上面的相同,这里就不写出来了

原文:https://blog.csdn.net/huaweichenai/article/details/90233294

微信小程序之分享功能

微信小程序之分享功能

小程序风口正盛,将小程序作为获客的来源之一实在合适不过,想要让小程序的获客产生裂变,那么从将小程序的数据发送出去势在必行,本文提供以下几种方案作为数据出口,达到老拉新/口碑传播的效果。

本文中所介绍的东西并没有高深的技术含量,都是一些很简单的技巧而已。

一、分享:

让用户使用小程序之后,再将它分享给好友,或者发送到朋友圈,实在太合适不过了。

1.转发给好友/群:

在小程序开发API中,发送给好友/群,可以有两种实现方式:

1)入口

a.小程序右上角自带的分享功能(…):

如果在当前页面调用wx.hideShareMenu()方法,那么右上角的分享功能将被隐藏,当然,隐藏方法与现实方法是承兑出现的,调用wx.showShareMenu()方法,可以显示该功能。

b.自定义分享按钮:<butto n open-type=’share’>分享</butto n>

以上两种方式均可实现分享功能

2)分享数据类型

不管采用以上何种方法,转发给好友的数据总归有它的数据模型,该数据模型是通过onShareAppMessage(options)返回的,也就是return一个object即可。其中,options.from可以用来判断是从自定义button打开的转发页面,还是从右上角的打开的转发页面。

以下是该object的数据模型:

如上所示,如果开发人员在onShareAppMessage(options)不进行任何处理,那么微信将会有一个默认的数据转发出去,title为当前小程序名称,path为当前页面的路径,imageUrl为当前页面的截图。根据imageUrl的定义,开发人员可以上传自定义图片,那么这个口子给了运营人员一定的发挥空间,这个问题,文章的后边会详细提及。

2.分享至朋友圈:

微信小程序目前没有直接提供方法来将小程序分享至朋友圈,不过可以采用曲线救国的方式来达到目的。

曲线救国的方式分为两步:

1.通过浏览器将希望分享的东西分享至朋友圈:

微信小程序自身没有任何入口可以进入到微信的浏览器中,那么就更加不可能让用户进入到自身操作系统中的浏览器进行分享了。

那么能否有其他的途径可以达到此目的呢?

答案是客服消息。

微信小程序本身提供客服消息是用来更好的为客户服务

小程序提供了入口,允许用户给客服发送消息,同时,也允许小程序的客服主动给用户发送消息,其中,可以发送图文链接

开发者可以在用户打开该聊天对话框时,主动给用户发送图文链接,用户点击该链接之后,将会跳转到微信的浏览器(H5)页面,该页面不同于小程序内打开的H5页面,如下图

开发者和用户对于这种样式的页面应该相当熟悉了,至此,从小程序进行分享至朋友圈的第一步完成了。

2.用户分享至朋友圈后,用户的好友通过该链接进入朋友圈

众所周知,微信目前还并未提供入口,将微信小程序直接在朋友圈进行展示,但是同样的,微信也没有禁止在朋友圈内展示小程序码,而我们通过小程序进行分享的是图文链接,那么图片自然就可以是需要分享的微信小程序码,至于文字,还可以作为运营人员的推广。

以上,就完成了从微信小程序分享至好友/好友群/朋友圈的路径。

注:小程序的二维码分两种,一种是常规的二维码,还有一种是小程序码,我们这里进行分享的是小程序码。

二、数据追踪

运营人员经常会期望知道哪些用户是自然量,哪些用户是推广量,不仅如此,他们常常期望给那些乐于分享的用户一些奖励。

那么,奖励的标准是什么?无外乎谁拉来的人多,谁就可以获得更多的奖励。开发人员需要满足运营的需求,所以需要记录每个用户通过分享获客的数量等等。

如何进行记录呢,还是老生常谈,无外乎以下几种方式:

1.简单粗暴型:

比如Uber和滴滴的获客方式,通过邀请码来进行获客。这种通过现金奖励的土豪方式不适合绝大多数的推广,而且简单粗暴,本文不再赘述。

2.数据匹配型:

现有的一些第三方推广渠道的合作方式常常都是如此,比如iOS通过用户的IDFA来进行标记用户,用户通过第三方app打开第三方渠道的短链时,由app将IDFA传给短链进行记录,当用户注册账号时,app端通过获取IDFA来和第三方渠道进行比对,如果一致,则认为是通过第三方渠道推广而来的量,最后进行结算。

微信小程序也可以模仿该方式进行记录。

上文提供了三种分享的方式,分享给好友/好友群/朋友圈,它们需要使用不同的方式来进行记录。

1)朋友圈:

分享至朋友圈是通过分享小程序码来达到分享功能的,那么想要进行数据匹配,肯定是通过小程序码来做文章了。

通过调用微信的不同的接口,可以生成类型不同的小程序码,我们调用接口:https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN,具体参数如下:

关注参数scene和page即可,我们可以将用户的userid或者唯一标识放入其中,这样在其他被拉进小程序的用户打开page页面时,我们可以通过以下方式获取到分享发起者的用户唯一标识:

此时,便可以根据此唯一标识来给对应的用户发放奖励了。

2)分享至好友/群:

分享至好友/群和分享至朋友圈的内容并不一致,后者是分享图文链接,而分享至好友群的往往是小程序本身,群中的用户通过该分享可以直接进入小程序,那么如何进行数据匹配呢?

其实方法大同小异,通过查看微信小程序的api,如下:

此处的path中可以加入用户的唯一标识,接下来的流程和分享至朋友圈便是一样了。

部分运营人员期望能知道分享的群的一些信息,可以参考此文:http://news.ifeng.com/a/20170510/51071063_0.shtml

本文参考微信小程序开发文档:

1.转发:https://mp.weixin.qq.com/debug/wxadoc/dev/api/share.html

2.客服消息:https://mp.weixin.qq.com/debug/wxadoc/dev/api/custommsg/conversation.html

3.获取二维码:https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html

原文:https://www.jianshu.com/p/c100d21bcc9c

微信小程序navigateBack如何带参数

wx.navigateBack({//返回

delta:1

})

方法如下:

一.

var pages = getCurrentPages();

var prevPage = pages[pages.length – 2]; //上一个页面

//直接调用上一个页面的setData()方法,把数据存到上一个页面中去

prevPage.setData({

mydata: {a:1, b:2}

})

二.

回到上一页,在data里定义mydata,然后在onshow里

var pages = getCurrentPages();

var currPage = pages[pages.length – 1]; //当前页面

console.log(currPage) ,就可以看到data里mydata的值了

小程序上传图片or文件到阿里云OSS

搞了大半天,累死了,原本在阿里云官网通过后台取签上传的方式,前端会用到lib,例子下载后无法加入到小程序中使用,后来在CSDN的一篇博文里找到了解决方案

后端get.php,callback.php从阿里云例子中取,直接用

get.php代码

<?php
    function gmt_iso8601($time) {
        $dtStr = date("c", $time);
        $mydatetime = new DateTime($dtStr);
        $expiration = $mydatetime->format(DateTime::ISO8601);
        $pos = strpos($expiration, '+');
        $expiration = substr($expiration, 0, $pos);
        return $expiration."Z";
    }

    $id= 'xxxxxxxx';          // 请填写您的AccessKeyId。
    $key= 'xxxxxxxx';     // 请填写您的AccessKeySecret。
    // $host的格式为 bucketname.endpoint,请替换为您的真实信息。
    $host = 'https://bucket名称.oss-cn-地域.aliyuncs.com/';  
    // $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。
    $callbackUrl = 'callback.php的网络路径';
    $dir = '文件保存路径';          // 用户上传文件时指定的前缀。
	
    $callback_param = array('callbackUrl'=>$callbackUrl, 
                 'callbackBody'=>'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}', 
                 'callbackBodyType'=>"application/x-www-form-urlencoded");
    $callback_string = json_encode($callback_param);

    $base64_callback_body = base64_encode($callback_string);
    $now = time();
    $expire = 30;  //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。
    $end = $now + $expire;
    $expiration = gmt_iso8601($end);


    //最大文件大小.用户可以自己设置
    $condition = array(0=>'content-length-range', 1=>0, 2=>1048576000);
    $conditions[] = $condition; 

    // 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
    $start = array(0=>'starts-with', 1=>'$key', 2=>$dir);
    $conditions[] = $start; 


    $arr = array('expiration'=>$expiration,'conditions'=>$conditions);
    $policy = json_encode($arr);
    $base64_policy = base64_encode($policy);
    $string_to_sign = $base64_policy;
    $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));

    $response = array();
    $response['accessid'] = $id;
    $response['host'] = $host;
    $response['policy'] = $base64_policy;
    $response['signature'] = $signature;
    $response['expire'] = $end;
    $response['callback'] = $base64_callback_body;
    $response['dir'] = $dir;  // 这个参数是设置用户上传文件时指定的前缀。
    echo json_encode($response);
?>

callback.php不用改

小程序前端:

uploadAliyun(str){   //str是wx.chooseImage返回的res.tempFilePaths[0]
  var that = this;
  wx.uploadFile({
    url: 'xxxx/get.php', //你的服务器地址
    filePath: str, //要上传文件资源的路径
    name: 'headimg', //文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容
    formData: {
	adminid: app.globalData.adminid  //HTTP 请求中其他额外的参数比如 用户id
    },
    success(res) {
        console.log(res)
        if(res.statusCode == 200){
          var info = JSON.parse(res.data);
          //  随机生成文件名称
          var fileRandName = Date.now() + "" + parseInt(Math.random() * 1000)
          var fileName = fileRandName + '.' + that.get_suffix(str)
          wx.uploadFile({
            url: 'https://bucket名称.oss-cn-地域.aliyuncs.com', 
            filePath: str,
            name: 'file',
            formData: {
              name: str,
              key: info.dir + fileName,
              policy: info.policy,
              signature: info.signature,
              expire : info.expire,
              success_action_status: "200",
              host: info.host,
              OSSAccessKeyId : info.accessid
            },
            success: function (res) {
              var data = res.data
              console.log(res)
              if(res.statusCode == 200){ }
            }
          })
        }
    }
   })
  },

补充get_suffix功能函数

get_suffix: function(filename) {
    var pos = filename.lastIndexOf('.')
    var suffix = ''
    if (pos != -1) {
        suffix = filename.substring(pos)
    }
    return suffix;
  },

js实现replaceAll方法

js本来有replace方法,请看w3school的说明:

  replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

语法:

  stringObject.replace(regexp/substr,replacement)

  第一个参数为一个字符串或者一个正则表达式,第二个参数为一个字符串或者一个用于生成字符串的函数。

注意重点:

  如果 regexp 具有全局标志 g,那么 replace() 方法将替换所有匹配的子串。否则,它只替换第一个匹配子串。

实例:

var str = "dogdogdog";
var str2 = str.replace("dog","cat");
console.log(str2);

这里仅替换第一个dog字符串,输出为:catdogdog。

js中是没有replaceAll方法的,那么如何实现替换所有匹配的字符串呢,即在js中实现replaceAll方法:

1. 使用具有全局标志g的正则表达式

var str = "dogdogdog";
var str2 = str.replace(/dog/g,"cat");
console.log(str2);

实现替换全部匹配字符串,输出结果为:catcatcat。

2. 使用另一种具有全局标志g的正则表达式的定义方法

var str = "dogdogdog";
var str2 = str.replace(new RegExp("dog","gm"),"cat");
console.log(str2);

输出结果同上例。这里g表示执行全局匹配,m表示执行多次匹配。

3. 给string对象添加原型方法replaceAll()

String.prototype.replaceAll = function(s1, s2) {
    return this.replace(new RegExp(s1, "gm"), s2);
}

这样就可以像使用replace方法一样使用replaceAll方法:

var str = "dogdogdog";
var str2 = str.replaceAll("dog", "cat");
console.log(str2);

输出结果同上例。
个人推荐使用第3种方法。

原文:https://www.cnblogs.com/henuyuxiang/p/11609088.html