浙政钉小程序总结

浙政钉小程序总结

  1. 扫码进入浙政钉小程序指定页面后 前端怎么获取到里面的参数
    首先生成二维码的链接: 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=测试编码后为 pages%2findex%2findex%3fqrCodeId%3d168%26appId%3d1%26appName%3d%e6%b5%8b%e8%af%95 将下划线即编码后的字符串赋值给page。此时在指定页面中可以直接在onLoad的函数中通过options.appId等获取参数值。
  2. 下拉刷新的事件不会触发
    首先看下当前页面的.json文件中是否配置了 "pullRefresh": true ,同时app.json中的window对象中也需要配置"allowsBounceVertical": "YES"。如果两个值都配置了还是不可以进行下拉刷新或上拉加载那就是css样式问题导致了,当页面内容不满时不会触发上拉加载。
  3. 生命周期中的onLaunch和page.onLoad
    正常情况下,打印日志或一些静态方法等可以看到是先打印app.js中onLaunch然后再试onLoad函数,但是如果是异步操作,比如你在小程序运行时onLaunch中刷新下Token,然后在首页的onLoad 函数中用这个刷新的token是不存在的,事实上会先执行page.onLoad函数中的异步请求,再执行onLaunch中的异步请求。和vue中created函数和mounted函数是完全不一样,这种情况下可以在首页去做onLaunch中的异步操作。
  4. 获取授权码
    在编辑器中调用方法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;
  5. websocket
    浙政钉小程序中每次建立websocket链接都需要重新监听其相关事件,如接受消息的onSocketMessage,以及监听链接成功的onSocketOpen等等。
  6. 自己封装的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
}
posted @ 2020-11-23 11:29  Smile_ruo  阅读(2251)  评论(0编辑  收藏  举报