001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.wechat;
017
018import com.jfinal.kit.Kv;
019import com.jfinal.kit.StrKit;
020import com.jfinal.weixin.sdk.api.*;
021import com.jfinal.weixin.sdk.kit.ParaMap;
022import com.jfinal.weixin.sdk.utils.HttpUtils;
023import com.jfinal.weixin.sdk.utils.RetryUtils;
024import io.jboot.utils.HttpUtil;
025
026import java.util.concurrent.Callable;
027
028public class WechatApis {
029
030
031    public static ApiResult createMenu(String jsonString) {
032        return MenuApi.createMenu(jsonString);
033    }
034
035
036    /**
037     * 网页授权获取用户信息,必须是最新的token,才能获得完整的用户资料
038     *
039     * @param token
040     * @param openId
041     * @return
042     */
043    public static ApiResult getUserInfo(String token, String openId) {
044        Kv pm = Kv.by("access_token", token).set("openid", openId).set("lang", "zh_CN");
045        String jsonResult = HttpUtil.httpGet("https://api.weixin.qq.com/sns/userinfo", pm);
046
047        if (jsonResult == null)
048            return null;
049
050        return new ApiResult(jsonResult);
051    }
052
053    /**
054     * 获取微信的openId
055     *
056     * @param code
057     * @return
058     */
059    public static ApiResult getAccessTokenAndOpenId(String code) {
060
061        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
062                + "appid={appid}"
063                + "&secret={secret}"
064                + "&code={code}"
065                + "&grant_type=authorization_code";
066
067        String getOpenIdUrl = url.replace("{appid}", ApiConfigKit.getAppId())
068                .replace("{secret}", ApiConfigKit.getApiConfig().getAppSecret())
069                .replace("{code}", code);
070
071        String jsonResult = HttpUtil.httpGet(getOpenIdUrl);
072
073        if (jsonResult == null)
074            return null;
075
076        return new ApiResult(jsonResult);
077    }
078
079
080    public enum JsApiType {
081        jsapi, wx_card
082    }
083
084    private static String apiUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
085
086    /**
087     * http GET请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket)
088     *
089     * @param jsApiType jsApi类型
090     * @return JsTicket
091     */
092    public static JsTicket getTicket(JsApiType jsApiType) {
093        String access_token = AccessTokenApi.getAccessTokenStr();
094        String appId = ApiConfigKit.getApiConfig().getAppId();
095        String key = appId + ':' + jsApiType.name();
096        final ParaMap pm = ParaMap.create("access_token", access_token).put("type", jsApiType.name());
097
098        // 2016.07.21修改By L.cm 为了更加方便扩展
099        String jsTicketJson = ApiConfigKit.getAccessTokenCache().get(key);
100        JsTicket jsTicket = null;
101        if (StrKit.notBlank(jsTicketJson)) {
102            jsTicket = new JsTicket(jsTicketJson);
103        }
104        if (null == jsTicket || !jsTicket.isAvailable()) {
105            // 最多三次请求
106            jsTicket = RetryUtils.retryOnException(3, new Callable<JsTicket>() {
107
108                @Override
109                public JsTicket call() throws Exception {
110                    return new JsTicket(HttpUtils.get(apiUrl, pm.getData()));
111                }
112
113            });
114
115            if (null != jsApiType) {
116                ApiConfigKit.getAccessTokenCache().set(key, jsTicket.getCacheJson());
117            }
118
119        }
120        return jsTicket;
121    }
122
123
124}