// Path: src/main/java/me/hao0/wechat/exception/WechatException.java
// public class WechatException extends RuntimeException {
// 
//     /**
//      * 微信返回的errcode
//      */
//     private Integer code;
// 
//     public WechatException(Map<String, ?> errMap) {
//         super("[" + errMap.get("errcode") + "]" + errMap.get("errmsg"));
//         code = (Integer)errMap.get("errcode");
//     }
// 
//     public WechatException() {
//         super();
//     }
// 
//     public WechatException(String message) {
//         super(message);
//     }
// 
//     public WechatException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public WechatException(Throwable cause) {
//         super(cause);
//     }
// 
//     protected WechatException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
//     public Integer getCode() {
//         return code;
//     }
// }
// 
// Path: src/main/java/me/hao0/wechat/model/qrcode/Qrcode.java
// public class Qrcode implements Serializable {
// 
//     private static final long serialVersionUID = -8864173402832984445L;
// 
//     /**
//      * 获取的二维码ticket，凭借此ticket可以在有效时间内换取二维码。
//      */
//     private String ticket;
// 
//     /**
//      * 有效时间(秒)
//      */
//     @JsonProperty("expire_seconds")
//     private String expireSeconds;
// 
//     /**
//      * 二维码图片解析后的地址，开发者可根据该地址自行生成需要的二维码图片
//      */
//     private String url;
// 
//     public String getTicket() {
//         return ticket;
//     }
// 
//     public void setTicket(String ticket) {
//         this.ticket = ticket;
//     }
// 
//     public String getExpireSeconds() {
//         return expireSeconds;
//     }
// 
//     public void setExpireSeconds(String expireSeconds) {
//         this.expireSeconds = expireSeconds;
//     }
// 
//     public String getUrl() {
//         return url;
//     }
// 
//     public void setUrl(String url) {
//         this.url = url;
//     }
// 
//     @Override
//     public String toString() {
//         return "Qrcode{" +
//                 "ticket='" + ticket + '\'' +
//                 ", expireSeconds='" + expireSeconds + '\'' +
//                 ", url='" + url + '\'' +
//                 '}';
//     }
// }
// 
// Path: src/main/java/me/hao0/wechat/model/qrcode/QrcodeType.java
// public enum QrcodeType {
// 
//     /**
//      * 临时二维码，有过期时间，最长7天，604800s
//      */
//     QR_SCENE("QR_SCENE"),
// 
//     /**
//      * 永久二维码，最多100000个
//      */
//     QR_LIMIT_SCENE("QR_LIMIT_SCENE"),
//     
//     /**
//      * 永久二维码，字符串类型，长度限制为1到64
//      */
//     QR_LIMIT_STR_SCENE("QR_LIMIT_STR_SCENE");
// 
//     private String value;
// 
//     private QrcodeType(String value){
//         this.value = value;
//     }
// 
//     public String value(){
//         return value;
//     }
// }


import com.google.common.collect.Maps;
import me.hao0.wechat.exception.WechatException;
import me.hao0.wechat.model.qrcode.Qrcode;
import me.hao0.wechat.model.qrcode.QrcodeType;
import me.hao0.common.json.Jsons;
import me.hao0.common.util.Strings;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import static me.hao0.common.util.Preconditions.*;
     * @param type	二维码类型，QR_SCENE为临时,QR_LIMIT_SCENE为永久,QR_LIMIT_STR_SCENE为永久的字符串参数值
     * @return	二维码参数
     */
    private Map<String, Object> buildQrcodeParams(String sceneId, String sceneStr, QrcodeType type) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(2);
        params.put("action_name", type.value());

        Map<String, Object> sceneMap = Maps.newHashMapWithExpectedSize(1);
        if (!Strings.isNullOrEmpty(sceneId)) {
        	sceneMap.put("scene_id", sceneId);
		}else if (!Strings.isNullOrEmpty(sceneStr)) {
        	sceneMap.put("scene_str", sceneStr);
		}
        
        Map<String, Object> scene = Maps.newHashMapWithExpectedSize(1);
        scene.put("scene", sceneMap);

        params.put("action_info", scene);
        return params;
    }

    /**
     * 获取二维码链接
     * @param ticket 二维码的ticket
     * @return 二维码链接，或抛WechatException
     */
    private String showQrcode(String ticket){
        try {
            return SHOW_QRCODE + URLEncoder.encode(ticket, "UTF-8");
        } catch (UnsupportedEncodingException e) {
// Path: src/main/java/me/hao0/wechat/exception/WechatException.java
// public class WechatException extends RuntimeException {
// 
//     /**
//      * 微信返回的errcode
//      */
//     private Integer code;
// 
//     public WechatException(Map<String, ?> errMap) {
//         super("[" + errMap.get("errcode") + "]" + errMap.get("errmsg"));
//         code = (Integer)errMap.get("errcode");
//     }
// 
//     public WechatException() {
//         super();
//     }
// 
//     public WechatException(String message) {
//         super(message);
//     }
// 
//     public WechatException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public WechatException(Throwable cause) {
//         super(cause);
//     }
// 
//     protected WechatException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// 
//     public Integer getCode() {
//         return code;
//     }
// }
// 
// Path: src/main/java/me/hao0/wechat/model/qrcode/Qrcode.java
// public class Qrcode implements Serializable {
// 
//     private static final long serialVersionUID = -8864173402832984445L;
// 
//     /**
//      * 获取的二维码ticket，凭借此ticket可以在有效时间内换取二维码。
//      */
//     private String ticket;
// 
//     /**
//      * 有效时间(秒)
//      */
//     @JsonProperty("expire_seconds")
//     private String expireSeconds;
// 
//     /**
//      * 二维码图片解析后的地址，开发者可根据该地址自行生成需要的二维码图片
//      */
//     private String url;
// 
//     public String getTicket() {
//         return ticket;
//     }
// 
//     public void setTicket(String ticket) {
//         this.ticket = ticket;
//     }
// 
//     public String getExpireSeconds() {
//         return expireSeconds;
//     }
// 
//     public void setExpireSeconds(String expireSeconds) {
//         this.expireSeconds = expireSeconds;
//     }
// 
//     public String getUrl() {
//         return url;
//     }
// 
//     public void setUrl(String url) {
//         this.url = url;
//     }
// 
//     @Override
//     public String toString() {
//         return "Qrcode{" +
//                 "ticket='" + ticket + '\'' +
//                 ", expireSeconds='" + expireSeconds + '\'' +
//                 ", url='" + url + '\'' +
//                 '}';
//     }
// }
// 
// Path: src/main/java/me/hao0/wechat/model/qrcode/QrcodeType.java
// public enum QrcodeType {
// 
//     /**
//      * 临时二维码，有过期时间，最长7天，604800s
//      */
//     QR_SCENE("QR_SCENE"),
// 
//     /**
//      * 永久二维码，最多100000个
//      */
//     QR_LIMIT_SCENE("QR_LIMIT_SCENE"),
//     
//     /**
//      * 永久二维码，字符串类型，长度限制为1到64
//      */
//     QR_LIMIT_STR_SCENE("QR_LIMIT_STR_SCENE");
// 
//     private String value;
// 
//     private QrcodeType(String value){
//         this.value = value;
//     }
// 
//     public String value(){
//         return value;
//     }
// }


// Path: src/main/java/me/hao0/wechat/core/QrCodes.java
import com.google.common.collect.Maps;
import me.hao0.wechat.exception.WechatException;
import me.hao0.wechat.model.qrcode.Qrcode;
import me.hao0.wechat.model.qrcode.QrcodeType;
import me.hao0.common.json.Jsons;
import me.hao0.common.util.Strings;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import static me.hao0.common.util.Preconditions.*;

     * @param type	二维码类型，QR_SCENE为临时,QR_LIMIT_SCENE为永久,QR_LIMIT_STR_SCENE为永久的字符串参数值
     * @return	二维码参数
     */
    private Map<String, Object> buildQrcodeParams(String sceneId, String sceneStr, QrcodeType type) {
        Map<String, Object> params = Maps.newHashMapWithExpectedSize(2);
        params.put("action_name", type.value());

        Map<String, Object> sceneMap = Maps.newHashMapWithExpectedSize(1);
        if (!Strings.isNullOrEmpty(sceneId)) {
        	sceneMap.put("scene_id", sceneId);
		}else if (!Strings.isNullOrEmpty(sceneStr)) {
        	sceneMap.put("scene_str", sceneStr);
		}
        
        Map<String, Object> scene = Maps.newHashMapWithExpectedSize(1);
        scene.put("scene", sceneMap);

        params.put("action_info", scene);
        return params;
    }

    /**
     * 获取二维码链接
     * @param ticket 二维码的ticket
     * @return 二维码链接，或抛WechatException
     */
    private String showQrcode(String ticket){
        try {
            return SHOW_QRCODE + URLEncoder.encode(ticket, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new WechatException(e);