小程序自用登录,自用请求二次封装(包后台)。

本文详细介绍了小程序的授权登录流程,包括API调用、请求处理、WebSocket连接、用户信息处理等。通过wx.login和getUserProfile接口获取用户信息,并结合后端Java服务实现用户注册与查询。同时,展示了如何处理微信接口返回的数据,以及异常情况的处理策略。
摘要由CSDN通过智能技术生成

 方便我自己扒

目录

项目结构目录

api.js

request.js(直接扒,适当改下回调)

base.js

socket.js(需求没有可以不用)

app.js(我们以openId为唯一标识,手机号另说)

 某个页面点击按钮授权登录JS

controller

service

serviceImpl

WechatUtil.java

application.yml

小程序常用工具 alert.js和utils.js


项目结构目录

api.js

import MyHttp from './request.js';

const ALL_API = {
  //用户注册
  wxInsertUser(data) {
    let result = {};
    result.method = "POST";
    result.url = '/wx/wxInsertUser';
    return result
  },
  //用户查询
  wxGetUser(data) {
    let result = {};
    result.method = "POST";
    result.url = '/wx/wxGetUser';
    return result
  },
}
const Api = new MyHttp(ALL_API);

export default Api;

request.js(直接扒,适当改下回调)

var baseUrl = require("../../utils/base.js");
import exceptionHandling from './exceptionHandling.js'

var deepCopy = function (o) {
  if (o instanceof Array) {
    var n = [];
    for (var i = 0; i < o.length; ++i) {
      n[i] = deepCopy(o[i]);
    }
    return n;

  } else if (o instanceof Object) {
    var n = {}
    for (var i in o) {
      n[i] = deepCopy(o[i]);
    }
    return n;
  } else {
    return o;
  }
}

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  return typeof obj;
} : function (obj) {
  return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};


function isObject(obj) {
  return (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null;
}

function sendRrquest(url, method, data, header) {

  let promise = new Promise(function (resolve, reject) {
    wx.showNavigationBarLoading() //在标题栏中显示加载
    wx.request({
      url: url,
      data: data,
      method: method,
      header: header,
      success: resolve,
      fail: reject,
      complete: function (res) {
        if (res.data != undefined){
          if (res.data.status === "B5000" || res.data.status === "5000") {
            // token过期处理
            exceptionHandling.tokenTimeout(res)
          }
          if (res.data.status === "9999") {
            // 服务器异常处理
            exceptionHandling.serverErr(res)
          }
        }
        wx.hideLoading();
        wx.hideNavigationBarLoading(); //完成停止加载
        wx.stopPullDownRefresh(); //停止下拉刷新
      }
    })
  });
  return promise;
};


function extend(obj) {
  for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }

  if (isObject(obj) && args.length > 0) {
    if (Object.assign) {
      return Object.assign.apply(Object, [obj].concat(args));
    }

    args.forEach(function (arg) {
      if (isObject(arg)) {
        Object.keys(arg).forEach(function (key) {
          obj[key] = arg[key];
        });
      }
    });
  }

  return obj;
}


function MyHttp(ALL_API) {
  let _build_url = baseUrl.base;
  let resource = {};
  for (let actionName in ALL_API) {
    let _config = ALL_API[actionName];
    resource[actionName] = (pdata) => {
      return sendRrquest(_build_url + _config(pdata).url, _config(pdata).method, pdata, {
        'content-type': 'application/json', "Authorization": "Bearer " + wx.getStorageSync("token")
      });
    }
  }
  return resource;
}

export default MyHttp;

base.js

// 小程序跳转版本 开发板: develop 体验版: trial 正式版: release
const envVersion = 'develop'; 
// WebSocket连接地址
const socketUrl = ""
// 上传图片地址
const uploadUrl = ''

// // 正式地址
// const base = ""

// // 测试服务器
// const base = ""

// 本地测试地址
const base = "http://192.168.1.138:8080/api"

module.exports = {
  uploadUrl: uploadUrl,
  base: base,
  envVersion,
  socketUrl
}

socket.js(需求没有可以不用)

/**
 * WebSocket配置文件
 * 
 * @date: 2021/6/8
 * @author: huo
 */
import base from './base.js';
const app = getApp();

const webScoket = {

  init() {
    // 监听连接成功
    this.onSocketOpen();
    // 监听连接是否关闭
    this.onSocketClose();
    //监听连接错误
    this.onSocketError();
    //连接
    this.connectSocket();
  },

  /**
   * 连接
   */
  connectSocket() {
    let _this = this;
    console.log(app.data.user);
    let url =  `${base.socketUrl}`+app.data.user.id
    console.log(url);
    wx.connectSocket({
      url:url,
    })
  },

  /**
   * 监听连接成功
   */
  onSocketOpen() {
    let _this = this;
    wx.onSocketOpen(() => {
      console.log('[WebSocket]: 已连接');
    })
  },

  /**
   * 监听连接关闭
   */
  onSocketClose() {
    let _this = this;
    wx.onSocketClose(() => {
      console.log('[WebSocket]: 已断开');
      // 重连(没有网络的情况下不重连)
      // _this.connectSocket();
    })
  },

  /**
   * 连接错误
   */
  onSocketError() {
    let _this = this;
    wx.onSocketError(error => {
      console.error('[socket error]:', error);
      // 重连(没有网络的情况下不重连)
      // _this.connectSocket();
    })
  },

  /**
   * 接收数据
   */
  onSocketMessage(callback) {
    console.log(12)
    let _this = this;
    wx.onSocketMessage(message => {
      console.log('[socket message]:', message);
      // 数据处理。方便界面中处理数据
      callback(message);
    })
  },


  /**
   * 发送指令
   */
  sendSocketMessage(msg) {
    let _this = this;
    wx.sendSocketMessage({
      data: msg,
      success(res) {
        console.log('[send message success]:', res);
      },
      fail(err) {
        console.log('[send message error]', err);
      }
    })
  },

  /**
   * 关闭连接
   */
  closeSocket() {
    let _this = this;
    wx.closeSocket();
  }
}

export default webScoket;

app.js(我们以openId为唯一标识,手机号另说)

// app.js
let util = require('/utils/tools/util.js');
let Api = require('/utils/config/api.js')
let alert = require('/utils/tools/alert.js')
const systemInfo = wx.getSystemInfoSync();
App({
  onLaunch() {
    //获取手机屏幕配置
    this.data.statusBarStyle = util.getStatusBarStyle()
    this.data.navigationBarStyle = util.getNavigationBarStyle()
    this.data.navigationStyle = util.getNavigationStyle()
    this.data.menuStyle = util.getMenuStyle()
    this.data.fixedTop = systemInfo.statusBarHeight
    this.data.bodyHeight = systemInfo.windowHeight - systemInfo.statusBarHeight - 100
    //登录
    this.login();
  },

  data: {
    user: null,
    statusBarStyle: '', //导航刘海头样式
    navigationBarStyle: '', //导航栏样式
    navigationStyle: '', //导航栏样式
    menuStyle: '', // 胶囊样式
    fixedTop: '', // 头部高度适配  
    bodyHeight: '', //去除statusBar和tabBar的剩下可用区域高度
  },

  /**
   * 登录 
   * */
  login() {
    let that = this;
    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        let code = res.code
        let _parms = {
          code: code
        };
        alert.showLogin();
        Api.default.wxGetUser(_parms).then((res) => {
          if (res.data.status === "success") {
            if (res.data.user == undefined) {
              that.data.user = null
            } else {
              that.data.user = res.data.user
              if (res.data.user.userName != undefined) {
                that.data.user.userName = util.uncodeUtf16(res.data.user.userName)
              }
              if (res.data.user.realName != undefined) {
                that.data.user.realName = util.uncodeUtf16(res.data.user.realName)
              }
            }
          } else {
            alert.alertModal1(res.data.msg);
          }
        }).catch((res) => {
          alert.alertModal("请求服务失败")
        })
      }
    })
  }
})

 某个页面点击按钮授权登录JS

/**
   * 最新获取用户头像和昵称接口
   */
  getUserProfile() {
    var that = this;
    wx.getUserProfile({
      desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        that.data.user.wxAvatar = res.userInfo.avatarUrl
        that.data.user.wxName = util.utf16toEntities(res.userInfo.nickName)
        that.data.user.sex = res.userInfo.gender
        wx.login({
          provider: 'weixin',
          success: function(res) {
            that.data.user.code = res.code
            that.addUser(that.data.user)
          }
        });
        console.log(res)
      },
      fail: (res) => {
        this.$refs.uToast.show({
          title: '授权失败',
          type: 'warning'
        })
        console.log(res)
      }
    })
  },

   /**
   * 添加用户
   */
  addUser(value){
    let that = this;
    if (value.sex !== undefined && value.sex != null) {
      switch (value.sex) {
        case 1:
          value.sex = '男';
          break;
        case 2:
          value.sex = '女';
          break;
        default:
          value.sex = '无';
          break;
      }
    }
    let _parms = value;
    Api.wxInsertUser(_parms).then((res) => {
      if(res.data.status === "success"){
        alertModal1("登录成功")
        app.data.user = res.data.user;
        if(res.data.user.userName != undefined){
          that.data.user.userName = util.uncodeUtf16(res.data.user.userName)
        }
        if(res.data.user.realName != undefined){
          that.data.user.realName = util.uncodeUtf16(res.data.user.realName)
        }
        that.getUser();
      }else{
        alertModal1(res.data.msg);
      }
    }).catch((res) => {
      alert.alertModal("请求服务失败")
    })
  },

controller

 /**
     * 插入用户
     * @return
     */
    @ResponseBody
    @RequestMapping("/wxInsertUser")
    public String wxInsertUser(@RequestBody String json){
        return questionService.wxInsertUser(json);
    }

    /**
     * 查询用户
     * @return
     */
    @ResponseBody
    @RequestMapping("/wxGetUser")
    public String wxGetUser(@RequestBody String json){
        return questionService.wxGetUser(json);
    }

service

String wxInsertUser(String json);

    String wxGetUser(String json);

serviceImpl

@Override
    public String wxInsertUser(String json) {
        JSONObject jsonObject = JSON.parseObject(json);
        Map map = new HashMap();
        try{
            String code = jsonObject.getString("code");
            String sex = jsonObject.getString("sex");
            String phone = jsonObject.getString("phone");
            String wxName = jsonObject.getString("wxName");
            String wxAvatar = jsonObject.getString("wxAvatar");

            //登录凭证不能为空
            if (code == null || code.length() == 0) {
                map.put("status", 0);
                map.put("msg", "code 不能为空");
                return JSON.toJSONString(map);
            }
            //解析相应内容(转换成json对象)
            JSONObject jsonObject1 = WechatUtil.getSessionKeyOrOpenId(code);
            //获取会话密钥(session_key)
            String session_key = jsonObject1.get("session_key").toString();
            //用户的唯一标识(openid)
            String openid = (String) jsonObject1.get("openid");
            UserEntity user = new UserEntity();
            user.setSex(sex);
            user.setPhone(phone);
            user.setAvatar(wxAvatar);
            user.setUserName(wxName);
            user.setOpenId(openid);
            String password = "123456";
            String pword = DigestUtils.md5DigestAsHex(password.getBytes());
            user.setPassword(pword);
            userMapper.insertUser(user);

            //2、对encryptedData加密数据进行AES解密
            map.put("status", "success");
            map.put("msg", "注册成功");
            map.put("user", user);
        }catch (Exception e){
            map.put("status", "error");
            map.put("msg", e.toString());
            e.printStackTrace();
        }
        return JSON.toJSONString(map);
    }

    @Override
    public String wxGetUser(String json) {
        JSONObject jsonObject = JSON.parseObject(json);
        Map map = new HashMap();
        try{
            String code = jsonObject.getString("code");
            //登录凭证不能为空
            if (code == null || code.length() == 0) {
                map.put("status", 0);
                map.put("msg", "code 不能为空");
                return JSON.toJSONString(map);
            }
            //解析相应内容(转换成json对象)
            JSONObject jsonObject1 = WechatUtil.getSessionKeyOrOpenId(code);
            //用户的唯一标识(openid)
            String openid = (String) jsonObject1.get("openid");
            UserEntity user = userMapper.getUserByOpenId(openid);
            //2、对encryptedData加密数据进行AES解密
            map.put("status", "success");
            map.put("msg", "查询用户成功");
            map.put("user", user);
        }catch (Exception e){
            map.put("status", "error");
            map.put("msg", e.toString());
            e.printStackTrace();
        }
        return JSON.toJSONString(map);
    }

WechatUtil.java

package com.dhrtec.exam.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.catalina.manager.HTMLManagerServlet;
import org.apache.xerces.impl.dv.util.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName WechatUtil
 * @Description TODO
 * @Author
 * @Date 2021/6/18
 * @Version 1.0
 */
@Configuration
public class WechatUtil {



    private static String appids;

    @Value("${weChat.appid}")
    private String appid;

    private static String secrets;

    @Value("${weChat.appsecret}")
    private String secret;

    @PostConstruct
    public void init(){
        appids = this.appid;
        secrets = this.secret;
    }

    public static JSONObject getSessionKeyOrOpenId(String code) {

        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
        //请求参数
        String params = "appid=" + appids + "&secret=" + secrets + "&js_code=" + code + "&grant_type=authorization_code";
        //发送post请求读取调用微信接口获取openid用户唯一标识
        JSONObject jsonObject = JSON.parseObject(HttpRequest.sendPost(requestUrl, params));
        return jsonObject;
    }
}

application.yml

weChat:
  appid: wx3a093b7d8bd24bfc
  appsecret: 10f30983169c7df644af2cda2ac81180

小程序常用工具 alert.js和utils.js

// alert.js

// 弹窗  showText : 提示文字
function alertModal(showText) {
  wx.showToast({
    title: showText,
    icon: 'none',
    duration: 2000,
    mask: true,
  })
}
//showModal: 提示文字
function promptModal(showText){
  wx.showModal({
    title: '提示',
    content: showText,
    showCancel: false,
  })
}
// 弹窗  showText : 提示文字
function alertModal1(showText) {
  wx.showToast({
    title: showText,
    icon: 'none',
    duration: 2000
  })
}
// 弹窗  showText : 提示文字
function showToast(showText) {
  wx.showModal({
    title: '提示',
    showCancel: false,
    content: showText
  })
}

function showLoading() {
  wx.showLoading({
    title: '加载中...',
    mask: true,
  })
}

function showLogin() {
  wx.showLoading({
    title: '校验登录中...',
    mask: true,
  })
}

function loading(showText) {
  wx.showLoading({
    title: showText,
    mask: true,
  })
}

module.exports = {
  alertModal: alertModal,
  showToast: showToast,
  promptModal: promptModal,
  showLoading: showLoading,
  loading: loading,
  showLogin: showLogin,
  alertModal1: alertModal1
}
const systemInfo = wx.getSystemInfoSync()
function getNowFormatDate() {  //yyyy-MM-dd HH:MM:SS”
  var date = new Date();
  var seperator1 = "/";
  var seperator2 = ":";
  var month = date.getMonth() + 1;
  var strDate = date.getDate();
  if (month >= 1 && month <= 9) {
    month = "0" + month;
  }
  if (strDate >= 0 && strDate <= 9) {
    strDate = "0" + strDate;
  }
  var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
    + " " + date.getHours() + seperator2 + date.getMinutes()
    + seperator2 + date.getSeconds();
  return currentdate;
}

function getNewDates() {  //yyyy-MM-dd”
  var date = new Date();
  var seperator1 = "-";
  var seperator2 = ":";
  var month = date.getMonth() + 1;
  var strDate = date.getDate();
  if (month >= 1 && month <= 9) {
    month = "0" + month;
  }
  if (strDate >= 0 && strDate <= 9) {
    strDate = "0" + strDate;
  }
  var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate;
  return currentdate;
}

function utf16toEntities(str) {  //将emoji表情转为字符进行存储 
  var patt = /[\ud800-\udbff][\udc00-\udfff]/g; // 检测utf16字符正则 
  str = str.replace(patt, function (char) {
    var H, L, code;
    if (char.length === 2) {
      H = char.charCodeAt(0); // 取出高位 
      L = char.charCodeAt(1); // 取出低位 
      code = (H - 0xD800) * 0x400 + 0x10000 + L - 0xDC00; // 转换算法 
      return "&#" + code + ";";
    } else {
      return char;
    }
  });
  return str;
}

function uncodeUtf16(str) {  //反解开EMOJI编码后的字符串   与上对应使用
  var reg = /\&#.*?;/g;
  var result = str.replace(reg, function (char) {
    var H, L, code;
    if (char.length == 9) {
      code = parseInt(char.match(/[0-9]+/g));
      H = Math.floor((code - 0x10000) / 0x400) + 0xD800;
      L = (code - 0x10000) % 0x400 + 0xDC00;
      return unescape("%u" + H.toString(16) + "%u" + L.toString(16));
    } else {
      return char;
    }
  });
  return result;
}

function reciprocal(cleartime) {  //倒计时
  if (!cleartime) {
    return 'no'
    return false
  }
  cleartime = new Date(cleartime);
  // cleartime = cleartime ? cleartime.replace(/-/g, "/") : '';
  let start = cleartime.getTime();
  start = start + 1 * 60 * 1000;
  let date = new Date();
  let now = date.getTime();
  let leftTime = start - now;
  let d, h, m, s;
  if (leftTime >= 0) {
    d = Math.floor(leftTime / 1000 / 60 / 60 / 24);  //天
    h = Math.floor(leftTime / 1000 / 60 / 60 % 24);  //时
    m = Math.floor(leftTime / 1000 / 60 % 60);  //分
    s = Math.floor(leftTime / 1000 % 60);  //秒
    if (s != 0) {
      return s + '秒后重发'
    }
  } else {
    return 'yes'
  }
}

function million(num) {    //数字过万处理
  return num > 9999 ? (Math.floor(num / 1000) / 10) + '万+' : num
}

function dateConv(dateStr, type) {  //   yyyy/mm/dd
  let year = dateStr.getFullYear(),
    month = dateStr.getMonth() + 1,
    today = dateStr.getDate();
  month = month > 9 ? month : "0" + month;
  today = today > 9 ? today : "0" + today;
  if (type == '-') {
    return year + "-" + month + "-" + today;
  } else {
    return year + "/" + month + "/" + today;
  }
}

let getQueryString = function (url, name) {  //识别普通二维码,跳转
  console.log("url = " + url)
  console.log("name = " + name)
  var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
  var r = url.substr(1).match(reg)
  if (r != null) {
    console.log("r = " + r)
    console.log("r[2] = " + r[2])
    return r[2]
  }
  return null;
}

/**
   * 获取胶囊按钮位置
   */
function getMenuPosition() {
  let top = 4
  let right = 7
  let width = 87
  let height = 32
  if (systemInfo.platform === 'devtools' && systemInfo.system.indexOf('Android') === -1) {
    top = 6
    right = 10
  }
  else if (systemInfo.platform === 'devtools' && systemInfo.system.indexOf('Android') != -1) {
    top = 8
    right = 10
  }
  else if (systemInfo.system.indexOf('Android') != -1) {
    top = 8
    right = 10
    width = 95
  }
  return {
    top: systemInfo.statusBarHeight + top,
    left: systemInfo.windowWidth - width - right,
    width: width,
    height: height
  }
}
/**
 * 获取状态栏样式
 */
function getStatusBarStyle() {
  let statusBarPosition = {
    top: 0,
    left: 0,
    width: systemInfo.windowWidth,
    height: systemInfo.statusBarHeight
  }
  return formatStyle(statusBarPosition)
}
/**
 * 获取导航栏样式
 */
function getNavigationBarStyle() {
  let menuPosition = getMenuPosition()
  let navigationBarPosition = {
    top: systemInfo.statusBarHeight,
    left: 0,
    width: systemInfo.windowWidth,
    height: (menuPosition.top - systemInfo.statusBarHeight) * 2 + menuPosition.height,
    "line-height": (menuPosition.top - systemInfo.statusBarHeight) * 2 + menuPosition.height
  }
  return formatStyle(navigationBarPosition)
}
/**
 * 获取导航样式
 */
function getNavigationStyle() {
  let menuPosition = getMenuPosition()
  let padding = systemInfo.windowWidth - menuPosition.left - menuPosition.width
  let navigationPosition = {
    top: menuPosition.top,
    left: padding,
    // width: systemInfo.windowWidth - padding * 3 - menuPosition.width,
    height: menuPosition.height,
  }
  return formatStyle(navigationPosition)
}
/**
 * 获取胶囊按钮样式
 */
function getMenuStyle() {
  return formatStyle(getMenuPosition())
}
/**
 * 格式化Style
 */
function formatStyle(position) {
  let styles = []
  for (let key in position) {
    styles.push(`${key}: ${position[key]}px;`)
  }
  return styles.join(' ')
}

module.exports = {
  utf16toEntities: utf16toEntities,
  uncodeUtf16: uncodeUtf16,
  million: million,
  getNowFormatDate: getNowFormatDate,
  getNewDates: getNewDates,
  reciprocal: reciprocal,
  dateConv: dateConv,
  getMenuPosition: getMenuPosition,
  getStatusBarStyle: getStatusBarStyle,
  getNavigationBarStyle: getNavigationBarStyle,
  getNavigationStyle: getNavigationStyle,
  getMenuStyle: getMenuStyle
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值