Micro-channel recording applet development filled pit

Recently because of the need to help his girlfriend to implement a micro-channel small program, so to get to know a bit small development programs. For the development of micro-channel applet, before it is completely no contact (with some front-end development experience), as a complete novice, starting materials must be micro-letter applet development documents , based on the experience of these days the development process point of view, a good idea Details of the document's official website over again, most of the pit because there is no read the document, while the other part of the pit is because the document did not write. . .

NOTE: Item schema is: C / S architecture, completely separated front and rear ends, the front end: the small micro-channel program, rear: springboot

The main pit development process encountered the following points:

  1. Log in micro-channel implementation module
    development documentation, landed logic description is clear, first of all applet calls wx.login () to obtain temporary registration certificate to provide micro-letter code, and then spread to the code developer server (our back-end servers), rear reuse applications and exclusive appid appsecret, code (just pass over the distal end code) as the three parameters, call micro-channel authorization url (https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret = SECRET & js_code = jSCODE & grant_type = authorization_code (APPID i.e. appid, SECRET i.e. appsecret, jSCODE i.e. code, other constant)), micro-channel authorization center returns two fields: user's unique identifier OpenID and a session key session_key of; for safety, is generally not as will session_key sessionId, but generate a sessionId myself, I was using sessionId generation and verification jwt technology.
    java implementation code:
@PostMapping("/wxLogin")
    public Result wxLogin(LoginVo loginVo) {
        log.info("wxLogin request:{}", loginVo);
        String url = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, String> param = new HashMap<>();
        param.put("appid", Constants.WEIXIN_APPID);
        param.put("secret", Constants.WEIXIN_SECRET);
        param.put("js_code", loginVo.getCode());
        param.put("grant_type", "authorization_code");

        String wxResult = HttpClientUtil.doGet(url, param);
        log.info("weixin response:{}", wxResult);

        WXSessionVo wxSessionVo = FastJsonUtil.fromJson(wxResult, WXSessionVo.class);
        if (wxSessionVo == null){
            return Result.fail(LOGIN_FAIL.getDesc(), LOGIN_FAIL.getCode());
        }
        UserInfo oldUserInfo = userInfoService.queryByOpenId(wxSessionVo.getOpenid());
        String token = "";
        if (oldUserInfo == null) {
            //写入数据库
            UserInfo newUserInfo = new UserInfo();
            newUserInfo.setHeaderUrl(loginVo.getHeaderUrl());
            newUserInfo.setUserName(loginVo.getUserName());
            newUserInfo.setOpenId(wxSessionVo.getOpenid());
            newUserInfo.setGmtDate(System.currentTimeMillis());
            userInfoService.save(newUserInfo);
            log.info("after userInfoService save, userInfo:{}", newUserInfo);
            token = TokenUtil.sign(newUserInfo.getId());
        } else {
            token = TokenUtil.sign(oldUserInfo.getId());
        }

        return Result.success(token);
    }
@Data
public class LoginVo implements Serializable {
    private String userName;

    private String headerUrl;

    private String code;

    private static final long serialVersionUID = 1L;


}

Front-end code to achieve:

wx.login({
            success: function(res) {
                var code = res.code; //登录凭证
                if (code) {
                    //2、调用获取用户信息接口
                    wx.getUserInfo({
                        success: function(res) {
                            app.globalData.userInfo = res.userInfo;
                            //3.请求自己的服务器,
                            var argu = {
                                code: code,
                                userName: res.userInfo.nickName,
                                headerUrl: res.userInfo.avatarUrl,
                            }
                            //这个地方换成wx.request方法发起http请求,我为了方便,所以封装了wx.request方法
                            httpClient.login(argu).then((data) => {
                                console.log("login http", data);
                                if (data.status == 200) {
                                //然后把token设置在每次的http请求中的header上,后端设置拦截器拿到token实现登陆逻辑的校验
                                    app.globalData.token = data.data;
                                    //如果后端校验成功,然后直接跳转到首页
                                    wx.switchTab({
                                        url: '../index/index'
                                    })
                                } else {
                                    wx.switchTab({
                                        url: '../auth/auth'
                                    })
                                }
                            }).catch(e => console.log(e));
                        },
                        fail: function() {
                            console.log('获取用户信息失败')
                        }
                    })
                } else {
                    console.log('获取用户登录态失败!' + r.errMsg)
                }
            },
            fail: function() {
                console.log('登陆失败')
            }
        });

It should be emphasized that this authorization landing page is a separate page, not the home page, then how to achieve this page to start a successful landing after a jump when the applet is loaded it home? In the global configuration in, there is a bold, then, represents the first array applet initial page (home page) , as long as all the pages on pages of this authorization in the first term can be executed first; after the successful landing Jump to the real home page.

//app.json
{
  "pages": ["pages/auth/auth", "pages/index/index"]
}

Note: I did, because nobody read the official document downloaded from github demo to see the landing page has not been authorized to call home, but home is better than the first to be carried out, deeply puzzled. Investigation for a long time, the problem was suspected to be the order of the configuration page, and then re-read the document only to find the answer turned out to be the case.

  1. Non Button button, by bindtap = "clickFunctionName", after clicking to achieve a corresponding method of triggering, certain parameters need to pass.
    • Scene: For item data show the list of articles with a for loop, and then click on a piece of data, the appropriate method of triggering, but need to know id that uniquely identifies this data
    • Ways: using data-parameter in the manner wxml, toDiary clicking implemented in the method: function (event) can be obtained when the parameter value, i.e., can be used event.currentTarget.dataset.patameter js obtained in binding value, if there is need to pass a plurality of parameters, a plurality of data-parameter like.

Note: There is a pit that customary manner java named parameters - hump nomenclature, when data-parameter bound parameters, and finally do not use this naming, because the event object, will automatically convert to a full parameterName to lower case, so the design is really pit against humanity ,,, For example, in wxml the data-tranctionId = "1", then the js e.currentTarget.dataset.tranctionId, so you never get less than the value of tranctionId but if e.currentTarget.dataset.tranctionid is to get the value of tranctionId; so in the applet, whether you are a data-tranctionId = "1", or data-tranctionid = "1", js can only use lowercase naming way to get e.currentTarget.dataset.tranctionid parameter values.

 <view class="content"  data-tranctionid="{{item.id}}" data-type="{{item.type}}" bindtap="toDiary">

toDiary: function(e) {
    console.log("toTopicOrDiary click", e)
    if (e.currentTarget.dataset.type == app.globalData.publishTypeEnum.topic) {
wx.navigateTo({
      url: '../topic/topic?topicId='+e.currentTarget.dataset.tranctionid
    })
    }else{
      wx.navigateTo({
      url: '../diary/diary?diaryId='+e.currentTarget.dataset.tranctionid
    })
    }
  },
  1. Front page url jump, get parameters on the url link in a new page
    • Scene: From the article list, click to jump to the article details the rules and articles
    • Ways: this is different from the normal web js acquisition parameters on the url embodiment, micro-channel applet, is url parameters into the new page objects onload options (options) method, the value of the parameter acquired way, options.parameterName.
// url: '../topic/topic?topicId='+e.currentTarget.dataset.tranctionid
onLoad: function(options) {
    console.log('options', options);
    var diaryId = options.topicId;
 }

Here, for the url parameter can be named using the nomenclature of the hump, you parameterName in options is not converted to lowercase ,,,

  1. After the dynamic data binding, how to change the value of a variable in js, the page automatically render the new value of the variable
  • Scene: the number of review articles show, just click to see the article details, have to get to the back end of the current number of comments, and then I add a comment at the bottom, so the number of reviews is to add 1.
  • Method to realize
<view class="operation-btn flex-item">
     <text>{{commentNum}}</text>
 </view>
//js
data: {
commentNum: 0
},
//修改data中属性的值有两种:
1. this.data.commentNum = this.data.commentNum + 1;
2. this.setData({
   commentNum: this.data.commentNum + 1
})
//两者的区别是,第一种,只会改变js中commentNum的值,但不会对页面中commentNum的值重新渲染刷新,
//而第二种是可以实现的页面中绑定的commentNum的值也被刷新。官方文档中竟然没有提示,,,
  1. uploader components upload pictures
    • Scene: In order to upload images directly using a micro-channel official uploader component weUI framework , to be honest, probably because it is a small program to develop a new white felt to write assembly demo is too simple, so how to upload to their own servers, and problems multi-map upload. . .
    • Method to realize:
uplaodFile(files) {
    console.log('upload files', files)
    var _this = this;
    //文件上传的函数,返回一个promise
    return new Promise((resolve, reject) => {
      for (var i = 0; i < files.tempFilePaths.length; i++) {
        wx.uploadFile({ //必须使用wx.uploadFile,而不是wx.request,我在这个地方试了半天,一直不成功,在github上找到合适的demo才发现问题
          url: URL.UPLOAD_DIARY_FILES, // 上传自己服务器的接口地址
          filePath: files.tempFilePaths[i],
          name: 'file', // 参数名称,后端接收时的参数名称
          formData: {},
          header: {
            "Content-Type": "multipart/form-data", //传文件必须是form-data类型
            'Authorization': app.globalData.token
          },
          success: (res) => {
            // 图片上传成功后,后端会返回存到文件存储路径的id
            //注意这个地方,跟你正常wx.request返回的结果不一样,后端return返回的数据data在res.data中,且这个data是jsonString(字符串格式),而不是json格式,
            //我就说data.data一直报错,所以如果想通过对象引用字段的方式拿到某字段值,必须先进行json解析JSON.parse,这么重要的一点,官方文档竟然也没有说明,,,,
            var data = JSON.parse(res.data);
            _this.data.picUrlIds.push(data.data);
          },
          fail: (err) => {
            console.log("error", err)
          }
        })
      }
    })
  },

Note: Due to the small program has a special role, not to share all the source code of the applet out, please understand! If the junior partner what's the problem, you can learn to discuss the comments, after all, just get started and I was just a little white.

Published 151 original articles · won praise 104 · views 270 000 +

Guess you like

Origin blog.csdn.net/qq_35923749/article/details/104299455