
/*=============================================================================================
	author:ZhaoJun
	version:1.2
	email:2732810281@qq.com
=============================================================================================*/


//严格模式
/*-------------------------------------------------------------------------------------------*/	
'use strict';
/*-------------------------------------------------------------------------------------------*/
const query=require('querystring')
// 微信的操作
/*-------------------------------------------------------------------------------------------*/	
class index
{
	constructor(appid,appsecret)
	{
		this.appid=appid?appid:$ToolPay.wx.appid
		this.appsecret=appsecret?appsecret:$ToolPay.wx.appsecret
		this.accessToken	
		this.accessTokenRedis='$@wx_access_token'
		this.jsapi_ticket	
		this.jsapi_ticketRedis='$@wx_jsapi_ticket'
	}

	static com(data,des)
	{
		if(data.data)
		{
			if(data.data instanceof Object)
			{
				return data.data
			}
			else
			{
				try 
				{
					return JSON.parse(data.data)
				} 
				catch (error) 
				{
					return data.data
				}
			}
		}
		else
		{
			throw Error('[wx]失败-'+des)
		}
	}


	//发送模板消息
	async sendTemp(sendOption)
	{
		// touser（必填）：接收者（用户）的 openid
		// template_id（是）：所需下发的模板消息的id（上面已经说明）
		// page（此参数为小程序，可不填）：点击模板卡片后的跳转页面，仅限本小程序内的页面。支持带参数,（示例index?	foo=bar）。该字段不填则模板无跳转。
		// url（为服务号，可不填）：点击跳转
		// form_id（此参数为小程序必填）：表单提交场景下，为 submit 事件带上的 formId（e.detail.formId）；支付场景下，为本次支付 的 prepay_id
		// data（是）：模板内容，不填则下发空模板( "keyword2": {"value": "2018年3月26日","color": "#173177"})
		// color（否）：模板内容字体的颜色，不填默认黑色
		// emphasis_keyword（否）：模板需要放大的关键词，不填则默认无放大
		let data= await $Sys.model
		(
			'/request/fetch','post',
			[
				{
					host: 'api.weixin.qq.com',
					path: `/cgi-bin/message/template/send`,
					method: 'POST',
					headers:{'Content-Type':'application/json'},
					data:JSON.stringify(sendOption),
				},
				{access_token: await (this.getAccessToken())}		
			]
		);

		return index.com(data,'发送模板消息')
	}

	//得到基础AccessToken，和登录授权的AccessToken不一样
	async getAccessToken()
	{ 
		if(this.accessToken)return this.accessToken
		let is=await $DbRedis.$con.main.get(this.accessTokenRedis)
		if(is)return is
		const tokenUrl = 'https://api.weixin.qq.com/cgi-bin/token';
		let data=await $Sys.model('/request/fetch','get',[tokenUrl,{grant_type: 'client_credential',appid:this.appid,secret:this.appsecret}])
		data=index.com(data)
		if(!data.access_token)
		{
			console.error('[获取accessToken]\r\n',data)
			throw Error('[wx]获取accessToken失败')
		}

		await $DbRedis.$con.main.set(this.accessTokenRedis,data.access_token,'Ex','7000')
		this.accessToken=data.access_token
		return data.access_token
	}

	login(url=$ToolPay.wx.redirect_uri,state='',scope='snsapi_userinfo')
	{
		//scope=snsapi_base不弹出授权页面，直接跳转，只能获取用户openid
		//snsapi_userinfo 弹出授权页面，可通过openid拿到昵称、性别、所在地
		//snsapi_login用于网页，扫码登录,这是微信开放平台里的，上面两个是公众平台的
		//微信后台端登录回调域名，需要与此url端口域名全一致，后面不加路径
		var url=escape(url)
		let _url='/connect/oauth2/authorize'
		if(scope=='snsapi_login')_url='/connect/qrconnect'

		let loginUrl=`https://open.weixin.qq.com${_url}`;
		return `${loginUrl}?appid=${this.appid}${url?('&redirect_uri='+url):''}&response_type=code&scope=${scope}${state?('&state='):''}`;
	}

	async loginInfo(code,tag)
	{
		//code，网页从login拿到，小程序端直接可以拿到
		let loginCodeUrl='https://api.weixin.qq.com/sns/oauth2/access_token';
		let data=await $Sys.model('/request/fetch','get',[loginCodeUrl,{grant_type: 'authorization_code',code:code,appid:this.appid,secret:this.appsecret}])
		data= index.com(data)
		if(tag)return data
		
		let loginInfoUrl='https://api.weixin.qq.com/sns/userinfo';
		data=await $Sys.model('/request/fetch','get',[loginInfoUrl,{access_token:data.access_token,openid:data.openid}])
		return index.com(data)
	}

	async share(url,type='jsapi')
	{
		//url为当前页面url
		let data
		let shareUrl='https://api.weixin.qq.com/cgi-bin/ticket/getticket'

		if(!this.jsapi_ticket)this.jsapi_ticket=await $DbRedis.$con.main.get(this.jsapi_ticketRedis)
		if(!this.jsapi_ticket)
		{
			data=await $Sys.model('/request/fetch','get',[shareUrl,{access_token:await (this.getAccessToken()),type:type}])
			data=index.com(data)
			if(!data.ticket)throw Error('[wx]ticket')
			await $DbRedis.$con.main.set(this.jsapi_ticketRedis,data.ticket,'Ex','7000')
			this.jsapi_ticket=data.ticket
		}

		let obj=
		{
			jsapi_ticket:this.jsapi_ticket,noncestr:Math.random().toString(36).substr(2, 15),
			timestamp:parseInt(new Date().getTime() / 1000),url:url
		}
		let str=$Sys.model('/fun/com','sha1',[query.stringify(obj, null, null,{ encodeURIComponent: res=>res })])
		obj.signature=str
		obj.appid=this.appid
		// Reflect.deleteProperty(obj,'jsapi_ticket')
		// Reflect.deleteProperty(obj,'url')
		return obj
	}

}
/*-------------------------------------------------------------------------------------------*/    
module.exports=index;