浙政钉小程序总结
浙政钉小程序总结
- 扫码进入浙政钉小程序指定页面后 前端怎么获取到里面的参数
首先生成二维码的链接:taurus://taurusclient/action/open_app?appId=0201027143446479&type=2&page=pages%2Findex%2Findex%3FqrCodeId%3D168%26appId%3D1%26appName%3D%E6%B5%8B%E8%AF%95
;appId:指的是创建的小程序appId,type:2 表示小程序,page=“”指定进入的页面以及参数传递。page= 后面的字符串需要进行UrIEncode编码,例如:pages/index/index?qrCodeId=168&appId=1&appName=测试
编码后为将下划线即编码后的字符串赋值给page。此时在指定页面中可以直接在onLoad的函数中通过pages%2findex%2findex%3fqrCodeId%3d168%26appId%3d1%26appName%3d%e6%b5%8b%e8%af%95
options.appId
等获取参数值。 - 下拉刷新的事件不会触发
首先看下当前页面的.json文件中是否配置了"pullRefresh": true
,同时app.json中的window
对象中也需要配置"allowsBounceVertical": "YES"
。如果两个值都配置了还是不可以进行下拉刷新或上拉加载那就是css样式问题导致了,当页面内容不满时不会触发上拉加载。 - 生命周期中的onLaunch和page.onLoad
正常情况下,打印日志或一些静态方法等可以看到是先打印app.js中onLaunch然后再试onLoad函数,但是如果是异步操作,比如你在小程序运行时onLaunch中刷新下Token,然后在首页的onLoad 函数中用这个刷新的token是不存在的,事实上会先执行page.onLoad函数中的异步请求,再执行onLaunch中的异步请求。和vue中created函数和mounted函数是完全不一样,这种情况下可以在首页去做onLaunch中的异步操作。 - 获取授权码
在编辑器中调用方法my.getAuthCode().then((res)=>{ console.log(res) this.setData({ rescode:res.result.code }) })
会报错,此时不要慌,因为获取这个授权码需要在真机调试中才可以获取到。同时如果用my.
去获取取值时为res.result.code
,用dd.getAuthCode({}).then((res) => { resolve(res) })
取值为res.code
; - websocket
浙政钉小程序中每次建立websocket链接都需要重新监听其相关事件,如接受消息的onSocketMessage
,以及监听链接成功的onSocketOpen
等等。 - 自己封装的util.js分享下
状态码判断这块符合restful风格接口
import dd from 'gdt-jsapi';;
const ip = "192.168.0.167:8080";//龙
// const ip = "192.168.0.238:8080";//熊
// const ip = "192.168.0.37:8080";//王者
// const ip = "192.168.0.136:8080";//超
// const ip = "192.168.0.223:8080";//伟
// const ip = "192.168.0.46";//斌
const baseUrl = "http://"+ip;
const wsbaseUrl = "ws://"+ip+"/websocket";
/**
*
* @param {*} callback 获取免登授权码成功回调
*
*/
const getAuthCode = function () {
return new Promise((resolve, reject) => {
dd.getAuthCode({}).then((res) => {
resolve(res)
}).catch((err) => {
reject(err)
})
})
}
/**
*
* @param {*} content 弱提示内容
*/
const toast = function (content) {
dd.showToast({
content: content,
})
}
// 接口未调通错误处理
const errMsg = function (err) {
if (err.error == 19) {
// toast('异常http状态码错误' + err.status)
// toast(err.data.message || err.errorMessage)
// 处理下token失效等问题
exceptionMsg(err.data.code, err);
} else if (err.error == 11) {
toast('无权跨域')
} else if (err.error == 12) {
toast('网络出错如网络不通等')
} else if (err.error == 13) {
toast('请求超时')
} else if (err.error == 14) {
toast('解码失败,http请求返回的内容格式是与dataType设置的类型不一致')
} else {
toast(err.errorMessage)
}
};
// 针对于code码处理
const exceptionMsg = function (code, res,options) {
switch (parseInt(code)) {
case 2001:
clearStorage();
if(options){
console.log(options)
}
redirectTo('/pages/index/index')
break;
default:
toast(res.data.message || res.errorMessage);
return false;
}
}
const existsToken = function(url){
if(!getStorage('token') && url.indexOf('/tokens')==-1){
toast('token不存在')
return false;
}else{
return true;
}
};
/**
*
* @param {*} url 接口地址
* @param {*} data 所传参数
*/
const post = function (url, data, headers, options) {
headers = headers || {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + getStorage('token')
};
// setNewToken();
return new Promise((resolve, reject) => {
if(!existsToken(url)){
return
}
dd.httpRequest({
url: baseUrl + url,
method: "POST",
data: data,
headers: headers,
dataType: "json",
timeout: 50000
}).then(res => {
hideLoading()
dd.stopPullDownRefresh();
if (res.data.code == 0) {
resolve(res.data)
} else {
dd.stopPullDownRefresh()
reject(res.data)
exceptionMsg(res.data.code, res)
}
}).catch(err => {
hideLoading()
dd.stopPullDownRefresh()
errMsg(err)
reject(err.data)
})
})
}
/**
*
* @param {*} url 接口地址
* @param {*} data 所传参数
*/
const get = function (url, data, headers) {
headers = headers || {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + getStorage('token')
};
// setNewToken();
return new Promise((resolve, reject) => {
if(!existsToken(url)){
return
}
dd.httpRequest({
url: baseUrl + url,
method: "GET",
data: data,
dataType: "json",
timeout: 50000,
headers
}).then(res => {
hideLoading()
if (res.data && res.data.code == 0) {
resolve(res.data)
} else {
dd.stopPullDownRefresh()
reject(res.data)
exceptionMsg(res.data.code, res)
}
}).catch(err => {
hideLoading()
reject(err)
errMsg(err)
})
})
}
/**
* 刷新token
* */
const refreshToken = function () {
return new Promise((resolve, reject) => {
if (getStorage('expiresIn') && getStorage('token')) {
// 判断token的有效期
if ((Number(getStorage('expiresIn')) * 1000 - new Date().getTime()) < 1000 * 60 * 60 * 24 * 3) {
post('/tokens/' + getStorage('token') + '/update', {}, {}).then(res => {
clearStorage(['token'])
setStorage('expiresIn', res.data.expiresIn)
setStorage('token', res.data.accessToken)
setTimeout(() => {
resolve(res)
}, 1000);
}).catch((err) => {
reject(err)
})
} else {
reject({
errorMessage: 'token未过期'
})
}
}else{
reject({
errorMessage: ''
})
}
})
}
// 跳转成功页面
const toSuccess = function(res){
if(res.data.success){
navigateTo('/pages/success/success?title='+res.data.message+'&signature='+res.data.signature)
}else{
toast(res.data.message||res.message)
}
}
// 登录
const login = function (options) {
return new Promise((resolve, reject) => {
getAuthCode().then((res) => {
post('/tokens', {
grantType: 'mini_app',
apiKey:res.code,
secretKey: '',
}, {
'Content-Type': 'application/x-www-form-urlencoded'
},options).then(res => {
hideLoading()
resolve(res)
}).catch(err => {
hideLoading()
reject(err)
})
}).catch((err) => {
hideLoading()
toast(err.errorMessage)
})
})
}
/**
* 创建socket连接
* @param {*} url 目标服务器地址
* @param {*} data 请求参数
*/
const connectWebSocket = function (url, data) {
return new Promise((resolve,reject)=>{
closeSocket();
console.log(wsbaseUrl)
dd.connectSocket({
url: wsbaseUrl,
data: data,
header: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + getStorage('token')
},
method: "GET",
complete:function(res){
// console.log(res)
resolve(res)
}
});
})
console.log(wsbaseUrl + url)
};
/**
*
* @param {*} successBack 连接打开的成功回调函数
*/
const onSocketOpen = function () {
return new Promise((resolve,reject)=>{
dd.onSocketOpen({}).then(res => {
console.log(res)
resolve(res)
}).catch(err => {
console.log('连接打开失败')
console.error(err)
reject(err)
})
})
}
const onSocketError = function () {
dd.onSocketError({}).then(res => {
// console.log(res)
}).catch(err => {
console.error(err)
})
}
/**
*
* @param {String} toSendMessage 要发送的数据
* @param {*} successBack 成功回调
*/
const sendMessage = function (toSendMessage) {
return new Promise((resolve,reject)=>{
dd.sendSocketMessage({
data: toSendMessage, // 需要发送的内容
}).then(res => {
console.log('数据发送成功' + JSON.stringify(res))
resolve(res)
}).catch(err => {
console.error(err)
reject(err)
})
})
}
/**
* 关闭websocket
* */
const closeSocket = function () {
dd.closeSocket({}).then(res => {
console.log(res)
}).catch(err => {
console.error(err)
})
}
/**
*
* @param {*} callback websocket关闭后的回调函数
*/
const onSocketClose = function (callback) {
dd.onSocketClose({}).then(res => {
console.log('WebSocket已关闭')
callback && callback(res)
}).catch(err => {
console.error(err)
})
}
const onSocketMessage = function (callback) {
return new Promise((resolve,reject)=>{
dd.onSocketMessage({}).then(res => {
console.log('收到消息'+JSON.stringify(res))
resolve(res)
}).catch(err => {
console.error(err)
reject(err)
})
})
}
/**
* dateStr :时间字符串类似2020-11-11T02:32:03.000 0000
* fmt 所需要返回的格式
*/
const formatDate = function (dateStr, fmt) {
let dateArr = dateStr.split('T');
let yMr = dateArr[0].split('-');
let hms = dateArr[1].split('.')[0].split(':');
if (fmt == 'ymr') {
// return [...yMr];
return yMr[0] + '年' + yMr[1] + '月' + yMr[2] + '日'
} else if (fmt == 'hms') {
// return [...hms];
return hms[0] + ':' + hms[1] + ':' + hms[2]
} else if (fmt == 'ymrhms') {
// return [...yMr,...hms];
return yMr[0] + '年' + yMr[1] + '月' + yMr[2] + '日' + ' ' + hms[0] + ':' + hms[1] + ':' + hms[2]
}
// return [...ymr,...hms];
}
/**
*
* @param {*} url 带参地址
* @param {*} name 获取键值对中的键
*/
const getUrlParams = function (url, name) { // 不传name返回所有值,否则返回对应值
if (url.indexOf('?') == 1) { return false; }
url = url.substr(1);
url = url.split('&');
var name = name || '';
var nameres;
// 获取全部参数及其值
for (var i = 0; i < url.length; i++) {
var info = url[i].split('=');
var obj = {};
obj[info[0]] = decodeURI(info[1]);
url[i] = obj;
}
// 如果传入一个参数名称,就匹配其值
if (name) {
for (var i = 0; i < url.length; i++) {
for (const key in url[i]) {
if (key == name) {
nameres = url[i][key];
}
}
}
} else {
nameres = url;
}
// 返回结果
return nameres;
}
//-------------------------------------微信、钉钉 不同配置--------------------------
const token = dd.getStorageSync({ key: 'token' }).data;
/**
* 获取本地存储的值
* */
const getStorage = function (key) {
return dd.getStorageSync({ key: key }).data
}
/**
* 本地存储 同步
* 存储的值为number string Array类型 取值时直接my.util.getStorage(键名).value;
* 存储值为对象时 取值为my.util.getStorage(键名)
* * */
const setStorage = function (key, value) {
if (typeof (value) === 'string' || typeof (value) === 'number' || value.constructor === Array) {
dd.setStorageSync({
key: key,
data: value
});
} else {
dd.setStorageSync({
key: key,
data: {
...value
}
});
}
}
/**
* 删除本地存储中的指定值 不传key则默认清空所有缓存数据
* keyArr 格式 ['key1','key2']
* */
const clearStorage = function (keyArr) {
if (keyArr && keyArr.length > 0) {
keyArr.map((element, index) => {
dd.removeStorageSync({
key: element,
});
})
} else {
dd.clearStorageSync();
}
}
/**
*
* @param {*} text 设置导航栏标题
* @param {*} background 设置导航栏背景
*/
const topBarText = function (text, background) {
if (background) {
dd.setNavigationBar({
title: text,
backgroundColor: background,
})
} else {
dd.setNavigationBar({
title: text,
})
}
}
/**
*
* @param {*} callback 扫码后的回调
*/
const scanQrCode = function (callback) {
dd.scan({
type: 'all',
}).then((res) => {
callback&&callback(res)
}).catch((err) => {
})
}
/**
*
* @param {*} content 警示内容
* @param {*} callback 成功回调
* @param {*} title 警示标题
* @param {*} failback 失败回调
*/
const alert = function (content, callback, title, failback) {
dd.alert({
message: content,
title: title || "信息提示",
}).then(res => {
callback && callback(res)
}).catch(err => {
failback && failback(err)
})
}
/**
*
* @param {*} url 同级跳转地址
*/
const redirectTo = function (url) {
dd.redirectTo({
url: url,
})
}
/**
*
* @param {*} content 加载圈提示内容
*/
const showLoading = function (content) {
dd.showLoading({
text: content,
})
}
// 关闭加载圈
const hideLoading = function () {
dd.hideLoading({});
}
//页面跳转
const navigateTo = function (url) {
dd.navigateTo({
url: url,
})
}
// 重定向
const reLaunch = function (url) {
dd.reLaunch({
url: url,
})
}
/**
*
* @param {*} content 确认框提示内容
* @param {*} confirmText 确认按钮的文案
* @param {*} callback 确认的回调
*/
const confirm = function (content, confirmText, callback) {
dd.confirm({
title: "注意",
message: content,
buttonLabels: [
confirmText,
"取消"
],
}).then((result) => {
console.log(result)
if (result.buttonIndex === 0) {
callback && callback(result);
} else {
}
})
}
/*
根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
出生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性,偶数分给女性。
校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
出生日期计算方法。
15位的身份证编码首先把出生年扩展为4位,简单的就是增加一个19或18,这样就包含了所有1800-1999年出生的人;
2000年后出生的肯定都是18位的了没有这个烦恼,至于1800年前出生的,那啥那时应该还没身份证号这个东东,⊙﹏⊙b汗...
下面是正则表达式:
出生日期1800-2099 (18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])
身份证正则表达式 /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i
15位校验规则 6位地址编码+6位出生日期+3位顺序号
18位校验规则 6位地址编码+8位出生日期+3位顺序号+1位校验位
校验位规则 公式:∑(ai×Wi)(mod 11)……………………………………(1)
公式(1)中:
i----表示号码字符从由至左包括校验码在内的位置序号;
ai----表示第i位置上的号码字符值;
Wi----示第i位置上的加权因子,其数值依据公式Wi=2^(n-1)(mod 11)计算得出。
i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
Wi 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 1
*/
//身份证号合法性验证
//支持15位和18位身份证号
//支持地址编码、出生日期、校验位验证
const IdentityCodeValid = function (code) {
var city = { 11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江 ", 31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北 ", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏 ", 61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外 " };
var tip = "";
var pass = true;
if (!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)) {
tip = "身份证号格式错误";
pass = false;
}
else if (!city[code.substr(0, 2)]) {
tip = "地址编码错误";
pass = false;
}
else {
//18位身份证需要验证最后一位校验位
if (code.length == 18) {
code = code.split('');
//∑(ai×Wi)(mod 11)
//加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
//校验位
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
var ai = 0;
var wi = 0;
for (var i = 0; i < 17; i++) {
ai = code[i];
wi = factor[i];
sum += ai * wi;
}
var last = parity[sum % 11];
if (parity[sum % 11] != code[17]) {
tip = "校验位错误";
pass = false;
}
}
}
if (!pass) alert(tip);
return pass;
}
/**
* 校验名字
* @param {*} name 名字
*/
const NameValid = function (name) {
var nameTip = "";
var namePass = true;
if (name == '') {
nameTip = '姓名不可以为空';
namePass = false;
}
if (name && !/^([\u4e00-\u9fa5]{1,20}|[a-zA-Z\.\s]{1,20})$/.test(name)) {
nameTip = '姓名格式不正确请重新填写';
namePass = false;
}
if (!namePass) {
alert(nameTip);
}
return namePass
}
/**
* 判断是否免PIN
* @param {*} appId 应用ID
*/
const isNeverPIN = function (appId,qrCodeId) {
// http://192.168.0.136:8080/appcert/verifyFreePin?appId=1&certId=1
return new Promise((resolve, reject) => {
get('/appcert/verifyFreePin', {
appId,
qrCodeId
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
};
/**
* 获取二维码中地址栏参数
* @param {*} variable 地址
*/
const getQueryVariable = function (url,variable) {
var query = url.split('?')[2];
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) { return pair[1]; }
}
}
module.exports = {
post: post,
get,
login,
baseUrl: baseUrl,
formatDate: formatDate,
token: token,
getUrlParams: getUrlParams,
alert: alert,
redirectTo: redirectTo,
hideLoading: hideLoading,
navigateTo: navigateTo,
reLaunch: reLaunch,
scanQrCode: scanQrCode,
toast: toast,
getAuthCode: getAuthCode,
topBarText: topBarText,
confirm: confirm,
showLoading,
setStorage,
getStorage,
clearStorage,
IdentityCodeValid,
NameValid,
wsbaseUrl,
connectWebSocket,
onSocketOpen,
onSocketError,
sendMessage,
closeSocket,
onSocketClose,
onSocketMessage,
refreshToken,
isNeverPIN,
getQueryVariable,
toSuccess
}
当你微笑的时候,全世界都会对你微笑。