package com.ishop.mobile.api; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iplatform.base.PlatformRuntimeException; import com.iplatform.base.WechatConstants; import com.iplatform.base.util.RestTemplateUtils; import com.ishop.merchant.Constants; import com.ishop.mobile.BaseApi; import com.ishop.mobile.util.WechatUtils; import com.ishop.model.response.WeChatJsSdkConfigResponse; import com.ishop.model.response.WechatPublicShareResponse; import com.walker.infrastructure.utils.StringUtils; import com.walker.infrastructure.utils.UrlUtils; import com.walker.web.ResponseValue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.text.MessageFormat; import java.util.UUID; @RestController @RequestMapping("/front/wechat") public class WechatApi extends BaseApi { private RestTemplate restTemplate; @Value("${ishop.wechat-js-api-debug}") private boolean wechatJsApiDebug = false; @Autowired public WechatApi(RestTemplate restTemplate){ this.restTemplate = restTemplate; } /** * 微信公众号分享配置 * @return */ @RequestMapping(value = "/get/public/share", method = RequestMethod.GET) public ResponseValue getPublicShare(){ WechatPublicShareResponse response = new WechatPublicShareResponse(); response.setImage(this.getArgumentVariable(Constants.CONFIG_KEY_ADMIN_WECHAT_SHARE_IMAGE).getStringValue()); response.setTitle(this.getArgumentVariable(Constants.CONFIG_KEY_ADMIN_WECHAT_SHARE_TITLE).getStringValue()); response.setSynopsis(this.getArgumentVariable(Constants.CONFIG_KEY_ADMIN_WECHAT_SHARE_SYNOPSIS).getStringValue()); return ResponseValue.success(); } /** * 获取微信公众号js配置 * @param url * @return */ @RequestMapping(value = "/get/public/js/config", method = RequestMethod.GET) public ResponseValue getPublicJsConfig(String url){ logger.debug(url); url = UrlUtils.decode(url); logger.debug("decode_url = {}", url); String appId = this.getArgumentVariable(WechatConstants.WECHAT_PUBLIC_APPID).getStringValue(); if(StringUtils.isEmpty(appId)){ return ResponseValue.error("请先配置微信参数"); } String ticket = this.getWechatCache().getJsApiTicket(); if(StringUtils.isEmpty(ticket)){ logger.debug("缓存未找到微信'ticket',重新调用查询"); // String accessToken = this.acquirePublicAccessToken(appId, null); String accessToken = this.acquirePublicAccessToken(); String ticketUrl = MessageFormat.format(WechatConstants.WECHAT_PUBLIC_JS_TICKET_URL, accessToken); ObjectNode objectNode = RestTemplateUtils.getData(ticketUrl, this.restTemplate); if(objectNode == null){ throw new PlatformRuntimeException("微信平台接口异常,没任何数据返回!"); } logger.debug(objectNode.toString()); try{ if (objectNode.has("errcode") && !objectNode.get("errcode").asText().equals("0")) { if (objectNode.has("errmsg")) { // 保存到微信异常表 // wxExceptionDispose(data, StrUtil.format("微信获取accessToken异常,{}端", type)); throw new PlatformRuntimeException("微信接口调用失败:" + objectNode.get("errcode") + objectNode.get("errmsg")); } } ticket = objectNode.get("ticket").asText(); this.getWechatCache().putJsApiTicket(ticket); logger.info("调用一次微信远程接口获取'ticket',并缓存:{}", ticket); } catch (Exception ex){ throw new RuntimeException("json字符串转对象错误:" + objectNode, ex); } } WeChatJsSdkConfigResponse response = new WeChatJsSdkConfigResponse(); response.setUrl(url); response.setAppId(appId); response.setNonceStr(UUID.randomUUID().toString().replace("-", "")); response.setTimestamp(System.currentTimeMillis()/1000); String signature = WechatUtils.getJsSdkSign(response.getNonceStr(), ticket, String.valueOf(response.getTimestamp()), url); response.setSignature(signature); String[] apiArray = StringUtils.commaDelimitedListToStringArray(WechatConstants.PUBLIC_API_JS_API_SDK_LIST); response.setJsApiList(StringUtils.asList(apiArray)); response.setDebug(this.wechatJsApiDebug); logger.info("response = {}, ticket = {}", response, ticket); return ResponseValue.success(response); } // private String acquirePublicAccessToken(String appId, String type){ // String publicAccessToken = this.getWechatCache().getPublicAccessToken(); // if(StringUtils.isNotEmpty(publicAccessToken)){ // return publicAccessToken; // } // String secret = this.getArgumentVariable(WechatConstants.WECHAT_PUBLIC_APPSECRET).getStringValue(); // if (StringUtils.isEmpty(secret)) { // throw new PlatformRuntimeException("微信公众号secret未设置"); // } // // String url = MessageFormat.format(WechatConstants.WECHAT_ACCESS_TOKEN_URL, appId, secret); // logger.debug("url = {}", url); // ObjectNode objectNode = RestTemplateUtils.getData(url, this.restTemplate); // if(objectNode == null){ // throw new PlatformRuntimeException("微信平台接口异常,没任何数据返回!"); // } // logger.debug(objectNode.toString()); // WeChatAccessTokenVo accessTokenVo = null; // try { //// ObjectNode objectNode = JsonUtils.jsonStringToObjectNode(result); // if (objectNode.has("errcode") && !objectNode.get("errcode").asText().equals("0")) { // if (objectNode.has("errmsg")) { // // 保存到微信异常表 //// wxExceptionDispose(data, StrUtil.format("微信获取accessToken异常,{}端", type)); // throw new PlatformRuntimeException("微信接口调用失败:" + objectNode.get("errcode") + objectNode.get("errmsg")); // } // } // accessTokenVo = new WeChatAccessTokenVo(); // accessTokenVo.setAccessToken(objectNode.get("access_token").asText()); // accessTokenVo.setExpiresIn(objectNode.get("expires_in").asInt()); //// accessTokenVo = JsonUtils.jsonStringToObject(result, WeChatAccessTokenVo.class); // this.getWechatCache().putPublicAccessToken(accessTokenVo.getAccessToken(), accessTokenVo.getExpiresIn().longValue() - 1800L); // logger.info("调用一次微信远程接口获取'public_accessToken',并缓存:{}", accessTokenVo.getAccessToken()); // return accessTokenVo.getAccessToken(); // // } catch (Exception e) { // throw new RuntimeException("json字符串转对象错误:" + objectNode, e); // } // } }