All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.anyline.wechat.mp.util.WechatMPUtil Maven / Gradle / Ivy

There is a newer version: 8.7.2-20240916
Show newest version
/*
 * Copyright 2006-2023 www.anyline.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */




package org.anyline.wechat.mp.util;

import org.anyline.entity.DataRow;
import org.anyline.entity.DataSet;
import org.anyline.net.HttpUtil;
import org.anyline.util.*;
import org.anyline.util.encrypt.SHA1Util;
import org.anyline.wechat.entity.WechatAuthInfo;
import org.anyline.wechat.entity.WechatTemplateMessage;
import org.anyline.wechat.entity.WechatTemplateMessageResult;
import org.anyline.wechat.entity.WechatUserInfo;
import org.anyline.wechat.mp.entity.Menu;
import org.anyline.wechat.util.WechatConfig;
import org.anyline.wechat.util.WechatConfig.SNSAPI_SCOPE;
import org.anyline.wechat.util.WechatUtil;
import org.apache.http.HttpEntity;
import org.apache.http.entity.StringEntity;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

public class WechatMPUtil extends WechatUtil {
	private static DataSet jsapiTickets = new DataSet();

	private WechatMPConfig config = null;

	private static Hashtable instances = new Hashtable();


	static {
		Hashtable configs = WechatMPConfig.getInstances();
		for(String key:configs.keySet()){
			instances.put(key, getInstance(key));
		}
	}


	public static WechatMPUtil getInstance(){
		return getInstance(WechatMPConfig.DEFAULT_INSTANCE_KEY);
	} 
	public WechatMPUtil(WechatMPConfig config){
		this.config = config; 
	} 
	public WechatMPUtil(String key, DataRow config){
		WechatMPConfig conf = WechatMPConfig.parse(key, config); 
		this.config = conf; 
		instances.put(key, this); 
	} 
	public static WechatMPUtil reg(String key, DataRow config){
		WechatMPConfig conf = WechatMPConfig.register(key, config);
		WechatMPUtil util = new WechatMPUtil(conf); 
		instances.put(key, util); 
		return util; 
	} 
	public static WechatMPUtil getInstance(String key){
		if(BasicUtil.isEmpty(key)){
			key = WechatMPConfig.DEFAULT_INSTANCE_KEY;
		} 
		WechatMPUtil util = instances.get(key); 
		if(null == util){
			WechatMPConfig config = WechatMPConfig.getInstance(key);
			if(null != config) {
				util = new WechatMPUtil(config);
				instances.put(key, util);
			}
		} 
		return util; 
	} 
	 
	public WechatMPConfig getConfig() {
		return config;
	} 

	 
	public String getAccessToken(){
		return WechatUtil.getAccessToken(config);
	}

	public String getJsapiTicket(){
		String result = ""; 
		DataRow row = jsapiTickets.getRow("APP_ID", config.APP_ID); 
		if(null == row){
			String accessToken = getAccessToken(); 
			row = newJsapiTicket(accessToken); 
		}else if(row.isExpire()){
			jsapiTickets.remove(row); 
			String accessToken = getAccessToken(); 
			row = newJsapiTicket(accessToken); 
		} 
		if(null != row){
			result = row.getString("TICKET"); 
		} 
		return result; 
	} 
	public DataRow newJsapiTicket(String accessToken){
		DataRow row = new DataRow();
		if(ConfigTable.IS_DEBUG && log.isWarnEnabled()){
			log.warn("[CREATE NEW JSAPI TICKET][token:{}]",accessToken); 
		}
		if(BasicUtil.isNotEmpty(accessToken)){
			row.put("APP_ID", config.APP_ID);
			String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";
			String text = HttpUtil.get(url,"UTF-8").getText();
			log.warn("[CREATE NEW JSAPI TICKET][txt:{}]",text);
			DataRow json = DataRow.parseJson(text);
			if(json.containsKey("ticket")){
				row.put("TICKET", json.getString("ticket"));
				row.setExpires(json.getInt("expires_in", 0)*1000);
				row.setExpires(1000*60*5); // 5分钟内有效
				if(ConfigTable.IS_DEBUG && log.isWarnEnabled()){
					log.warn("[CREATE NEW JSAPI TICKET][TICKET:{}]",row.get("TICKET"));
				}
			}else{
				log.warn("[CREATE NEW JSAPI TICKET][FAIL]");
				return null;
			}
			jsapiTickets.addRow(row);
		}
		return row; 
	} 
	/** 
	 * 参与签名的字段包括 
	 * noncestr(随机字符串),  
	 * jsapi_ticket 
	 * timestamp(时间戳 
	 * url(当前网页的URL,不包含#及其后面部分) 
	 * 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后, 
	 * 使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1. 
	 * @param params  params
	 * @return String
	 */ 
	public String jsapiSign(Map params){
		String sign = ""; 
		sign = BeanUtil.map2string(params);
		sign = SHA1Util.sign(sign);
		return sign; 
	} 
	 
	public Map jsapiSign(String url){
		Map params = new HashMap(); 
		params.put("noncestr", BasicUtil.getRandomLowerString(32)); 
		params.put("jsapi_ticket", getJsapiTicket()); 
		params.put("timestamp", System.currentTimeMillis()/1000+""); 
		params.put("url", url); 
		String sign = jsapiSign(params); 
		params.put("sign", sign); 
		params.put("appid", config.APP_ID); 
		return params; 
	}

	public WechatAuthInfo getAuthInfo(String code){
		return WechatUtil.getAuthInfo(config, code);
	}
	public String getOpenId(String code){
		WechatAuthInfo info = getAuthInfo(code);
		if(null != info && info.isResult()){
			return info.getOpenid();
		}
		return null;
	}
	public WechatUserInfo getUserInfo(String openid){
		return WechatUtil.getUserInfo(config,openid);
	}
	public String getUnionId(String openid) {
		WechatUserInfo info = getUserInfo(openid);
		if (null != info && info.isResult()) {
			return info.getUnionid();
		}
		return null;
	}

	/** 
	 * 是否已关注 
	 * @param openid  openid
	 * @return boolean
	 */ 
	public boolean isSubscribe(String openid){
		WechatUserInfo info = getUserInfo(openid);
		if(null == info){
			return false; 
		}
		if("1".equals(info.getSubscribe())){
			return true; 
		} 
		return false; 
	}

	/**
	 * 创建登录连接
	 * @param key 配置文件的key默认default
	 * @param redirect redirect 登录成功后得定向地址
	 * @param scope scope 获取信息范围
	 * @param state state 原样返回
	 * @return String
	 */
	public static String createAuthUrl(String key, String redirect, SNSAPI_SCOPE scope, String state){
		String url = null;
		try{
			WechatConfig config = WechatMPConfig.getInstance(key);
			String appid = config.APP_ID;
			if(BasicUtil.isEmpty(scope)){
				scope = SNSAPI_SCOPE.BASE;
			}
			if(BasicUtil.isEmpty(redirect)){
				redirect = config.OAUTH_REDIRECT_URL;
			}
			if(BasicUtil.isEmpty(redirect)){
				redirect = WechatMPConfig.getInstance().OAUTH_REDIRECT_URL;
			}
			redirect = URLEncoder.encode(redirect, "UTF-8");
			url =  WechatConfig.URL_OAUTH + "?appid="+appid+"&redirect_uri="+redirect+"&response_type=code&scope="
					+scope.getCode()+"&state="+state+",app:"+key+"#wechat_redirect";
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		return url;
	}


	/**
	 * 发送样模板消息
	 * @param msg  msg
	 * @return WechatTemplateMessageResult
	 */
	public WechatTemplateMessageResult sendTemplateMessage(WechatTemplateMessage msg){
		WechatTemplateMessageResult result = null;
		String token = getAccessToken();
		String url = WechatConfig.API_URL_SEND_TEMPLATE_MESSAGE + "?access_token=" + token;
		if(null != msg) {
			String json = BeanUtil.object2json(msg);
			log.warn("[send template message][data:{}]", json);
			HttpEntity entity = new StringEntity(json, "UTF-8");
			String txt = HttpUtil.post(url, "UTF-8", entity).getText();
			log.warn("[send template message][result:{}]", txt);
			result = BeanUtil.json2oject(txt, WechatTemplateMessageResult.class);
		}
		return result;
	}
	public WechatTemplateMessageResult sendTemplateMessage(String openId, WechatTemplateMessage msg){
		if(null != msg) {
			msg.setUser(openId);
		}
		return sendTemplateMessage(msg);
	}
	// 生成场景二维码
	public DataRow createQrCode(String code){
		String token = getAccessToken();
		String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+token;
		Map params = new HashMap();
		String param = "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \""+code+"\"}}}";
		String result = HttpUtil.post(url,"UTF-8", new StringEntity(param,"UTF-8")).getText();
		return DataRow.parseJson(result);
	}

    /**
     * 生成临时二维码
	 * @param code 场景值
	 * @param sec 有效时间(秒)
	 * @return DataRow
	 */
	public DataRow createQrCode(String code, int sec){
		String token = getAccessToken();
		String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+token;
		Map params = new HashMap();
		String param = "{\"expire_seconds\":"+sec+", \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \""+code+"\"}}}";
		String result = HttpUtil.post(url,"UTF-8", new StringEntity(param,"UTF-8")).getText();
		return DataRow.parseJson(result);
	}

    /**
     * 为用户添加标签
	 * @param users 用户openid列表
	 * @param tag 标签id
	 * @return DataRow
	 */
	public DataRow addUserTag(List users, int tag){
		String token = getAccessToken();
		String url = "https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token="+token;
		Map params = new HashMap();
		params.put("openid_list", users);
		params.put("tagid", tag);
		String result = HttpUtil.post(url,"UTF-8", new StringEntity(BeanUtil.map2json(params),"UTF-8")).getText();
		return DataRow.parseJson(result);
	}

	/**
	 * 创建菜单
	 * @param menu 菜单内容
	 * @return 菜单id
	 */
	public String createMenu(Menu menu){
		String url = "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token="+getAccessToken();
		if(null == menu.getMatchrule()){
			url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+getAccessToken();
		}
		String result = HttpUtil.post(url, "UTF-8", new StringEntity(menu.toJson(),"UTF-8")).getText();
		DataRow row = DataRow.parse(result);
		String id = row.getString("menuid");
		menu.setMenuid(id);
		return id;
	}

	/**
	 * 删除所以菜单
	 * @return DataRow
	 */
	public DataRow deleteMenu(){
		String url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token="+getAccessToken();
		String result = HttpUtil.get(url).getText();
		DataRow row = DataRow.parse(result);
		return row;
	}

	/**
	 * 删除指定菜单
	 * @param menu 菜单id
	 * @return DataRow
	 */
	public DataRow deleteMenu(String menu){
		String param = "{\"menuid\":\""+menu+"\"}";
		String url = "https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token="+getAccessToken();
		String result = HttpUtil.post(url, "UTF-8", new StringEntity(param,"UTF-8")).getText();
		DataRow row = DataRow.parse(result);
		return row;
	}

	public DataRow getMenu(){
		String url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token="+getAccessToken();
		String result = HttpUtil.get(url).getText();
		DataRow row = DataRow.parseJson(result);
		return row;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy