|
- package com.iformall.controller;
-
- import com.google.gson.Gson;
- import com.google.gson.GsonBuilder;
- import com.iformall.common.Result;
- import com.iformall.common.ResultData;
- import com.iformall.domain.po.*;
- import com.iformall.enums.*;
- import com.iformall.mp.manager.WxMpManager;
- import com.iformall.service.*;
- import com.iformall.service.wechat.FmOpenService;
- import io.swagger.annotations.Api;
- import io.swagger.annotations.ApiOperation;
- import me.chanjar.weixin.common.error.WxErrorException;
- import me.chanjar.weixin.mp.api.WxMpService;
- import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
- import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
- import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
- import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
- import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
- import me.chanjar.weixin.open.bean.result.WxOpenPlatformResult;
- import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;
- import me.chanjar.weixin.open.bean.result.WxOpenResult;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.*;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.PrintWriter;
- import java.nio.charset.Charset;
- import java.text.SimpleDateFormat;
- import java.util.Date;
-
- @Controller
- @RequestMapping("/wxOpen")
- @Api(description = "微信第三方开放平台回调相关接口")
- public class WechatCalllbackController extends BaseController {
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- @Autowired
- protected FmOpenService openService;
-
- @Autowired
- private WxComponentVerifyTicketService componentVerifyTicketService;
-
- @Autowired
- private WxAuthorizerInfoService authorizerInfoService;
-
- @Autowired
- private WxWeappAuditStatusService weappAuditStatusService;
-
- @Autowired
- private WxAppinfoService appinfoService;
-
- @Autowired
- private MailService mailService;
-
- @Autowired
- private WxMpManager mpManager;
-
- @PostMapping(value = "/notify")
- @ApiOperation("接收ticket回调")
- @ResponseBody
- public String receiveTicket(HttpServletRequest request) throws IOException {
- logger.info("[" + getIpAddr() + "]接收微信回调 /wxOpen/notify");
-
- String timestamp = request.getParameter("timestamp");
- String nonce = request.getParameter("nonce");
- String signature = request.getParameter("signature");
- String encType = request.getParameter("encrypt_type");
- String msgSignature = request.getParameter("msg_signature");
-
- if (!StringUtils.equalsIgnoreCase("aes", encType)
- || !openService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
- throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
- }
-
- InputStream inStream = request.getInputStream();
- ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = inStream.read(buffer)) != -1) {
- outSteam.write(buffer, 0, len);
- }
- String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8"));
- logger.info(resultxml);
-
- outSteam.close();
- inStream.close();
-
- logger.info("\n接收微信回调:[signature=[{}], encType=[{}], msgSignature=[{}],"
- + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
- signature, encType, msgSignature, timestamp, nonce, resultxml);
-
- // aes加密的消息
- WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(resultxml,
- openService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
- this.logger.info("接收微信回调,消息解密后内容为:{} ", inMessage.toString());
- if (inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.COMPONENT_VERIFY_TICKET.getMessage())) {
- // 保存component_verify_ticket
- componentVerifyTicketService.saveOrUpdate(new WxComponentVerifyTicket() {
- {
- setComponentVerifyTicket(inMessage.getComponentVerifyTicket());
- setCreateTime(new Date(Long.valueOf(inMessage.getCreateTime() * 1000)));
- setComponentAppid(inMessage.getAppId());
- setDeadline(new Date(Long.valueOf(System.currentTimeMillis() + (60 * 60 * 1000))));
- }
- });
- } else if (inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.AUTHORIZED.getMessage()) ||
- inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.UPDATEAUTHORIZED.getMessage())) {
- // 审核通过
- try {
- WxOpenQueryAuthResult queryAuthResult = openService.getWxOpenComponentService().getQueryAuth(inMessage.getAuthorizationCode());
- logger.info("getQueryAuth", queryAuthResult);
-
- WxOpenAuthorizerInfoResult openAuthorizerInfoResult = openService.getWxOpenComponentService().getAuthorizerInfo(
- queryAuthResult.getAuthorizationInfo().getAuthorizerAppid());
- logger.info(openAuthorizerInfoResult.toString());
- // save auth info
- authorizerInfoService.saveOrUpdate(new WxAuthorizerInfo() {
- {
- setAuthorizerAppid(openAuthorizerInfoResult.getAuthorizationInfo().getAuthorizerAppid());
- setAlias(openAuthorizerInfoResult.getAuthorizerInfo().getAlias());
- setHeadImg(openAuthorizerInfoResult.getAuthorizerInfo().getHeadImg());
- setQrcodeUrl(openAuthorizerInfoResult.getAuthorizerInfo().getQrcodeUrl());
- setRefreshToken(openAuthorizerInfoResult.getAuthorizationInfo().getAuthorizerRefreshToken());
- setAccessToken(openAuthorizerInfoResult.getAuthorizationInfo().getAuthorizerAccessToken());
- setAccessTokenExpire(new Date(Long.valueOf(System.currentTimeMillis() + openAuthorizerInfoResult.getAuthorizationInfo().getExpiresIn()*1000)));
- setAuthorizationStatus(EnumWxAuthorizationStatus.AUTHORIZED.getCode());
- setAuthTime(new Date());
- }
- });
- } catch (WxErrorException e) {
- logger.error(e.getMessage());
- }
- } else if (inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.UNAUTHORIZED.getMessage())) {
- // 授权取消
- authorizerInfoService.saveOrUpdate(new WxAuthorizerInfo() {
- {
- setAuthorizerAppid(inMessage.getAuthorizerAppid());
- setAuthorizationStatus(EnumWxAuthorizationStatus.UNAUTHORIZED.getCode());
- setAuthTime(new Date());
- }
- });
- }
-
- try {
- String out = openService.getWxOpenComponentService().route(inMessage);
- this.logger.info("组装回复信息:{}", out);
- } catch (WxErrorException e) {
- this.logger.error("notify", e);
- }
-
- return "success";
- }
-
- @RequestMapping(value = "/{appId}/callback")
- @ApiOperation("消息回调")
- public void callback(@PathVariable("appId") String appId, HttpServletRequest request, HttpServletResponse response) throws IOException {
- logger.info("[" + getIpAddr() + "]接收微信APP回调 /{appId}/callback");
- String timestamp = request.getParameter("timestamp");
- String nonce = request.getParameter("nonce");
- String signature = request.getParameter("signature");
- String encType = request.getParameter("encrypt_type");
- String openid = request.getParameter("openid");
- String msgSignature = request.getParameter("msg_signature");
-
- // 第三方平台一定接收的是加密的消息
- if (!StringUtils.equalsIgnoreCase("aes", encType)
- || !openService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
- throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
- }
-
- InputStream inStream = request.getInputStream();
- ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = inStream.read(buffer)) != -1) {
- outSteam.write(buffer, 0, len);
- }
- String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8"));
- logger.info(resultxml);
-
- outSteam.close();
- inStream.close();
-
- logger.info("接收微信APP回调:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"
- + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
- appId, openid, signature, encType, msgSignature, timestamp, nonce, resultxml);
-
-
- String out = "";
- // aes加密的消息
- WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(resultxml,
- openService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
- logger.info("接收微信APP回调,消息解密后内容为:\n{}", inMessage.toString());
-
- // 全网发布测试用例
- if (StringUtils.equalsAnyIgnoreCase(appId, "wx570bc396a51b8ff8", "wxd101a85aa106f53e")) {
- try {
- if (StringUtils.equals(inMessage.getMsgType(), "text")) {
- if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) {
- out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(
- WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback")
- .fromUser(inMessage.getToUser())
- .toUser(inMessage.getFromUser())
- .build(),
- openService.getWxOpenConfigStorage()
- );
- } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) {
- String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";
- WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build();
- openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);
- }
- } else if (StringUtils.equals(inMessage.getMsgType(), "event")) {
- WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build();
- openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);
- }
- } catch (WxErrorException e) {
- logger.error("callback", e);
- }
-
- PrintWriter printWriter = response.getWriter();
- printWriter.print("success");
- printWriter.flush();
- printWriter.close();
- return;
- }
-
- WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId);
-
- PrintWriter printWriter = response.getWriter();
-
- if(authorizerInfo != null &&
- (authorizerInfo.getType().equals(EnumAppType.B.getCode()) ||
- authorizerInfo.getType().equals(EnumAppType.C.getCode()))) {
- // 小程序 审核 消息
- /**判断消息类型,调用对应的方法*/
- switch (inMessage.getMsgType()) {
- case "event": {
- switch (inMessage.getEvent()) {
- case "weapp_audit_success": { // 审核成功
- updateAuditStatus(appId, true, "");
- break;
- }
- case "weapp_audit_fail": { // 审核失败
- updateAuditStatus(appId, false, inMessage.getReason());
- break;
- }
- default:
- break;
- }
- printWriter.print("success");
- printWriter.flush();
- printWriter.close();
- return;
- }
- case "text":
- WxMpXmlOutMessage outMessage = openService.getWxOpenMessageRouter().route(inMessage, appId);
- if (outMessage == null) {
- printWriter.print("success");
- printWriter.flush();
- printWriter.close();
- return;
- }
- // out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, openService.getWxOpenConfigStorage());
- // logger.info(out);
- break;
- default:
- printWriter.print("success");
- printWriter.flush();
- printWriter.close();
- return;
- }
- } else {
- // 公众号
- WxMpService mpService = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId);
- try {
- WxMpXmlOutMessage outMessage = mpManager.getRouter(mpService).route(inMessage);
- if (outMessage == null) {
- this.logger.info("2 return: success");
- printWriter.print("success");
- printWriter.flush();
- printWriter.close();
- return;
- }
- // logger.info("组装回复" + outMessage.toXml());
- // out = outMessage.toEncryptedXml(mpService.getWxMpConfigStorage());
- // logger.info("组装回复消息-->"+out);
- } catch (Exception e) {
- logger.error("路由消息时出现异常!", e);
- }
- }
-
- printWriter.print("success");
- printWriter.flush();
- printWriter.close();
- }
-
- private void updateAuditStatus(String appId, boolean success, String reason) {
-
-
- WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId);
- if (auditStatus != null) {
- if (success) {
- auditStatus.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode());
- auditStatus.setAuditErrCode("");
- } else {
- auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode());
- auditStatus.setAuditErrCode(reason);
- }
- auditStatus.setAuditTime(new Date());
- weappAuditStatusService.updateStatus(auditStatus);
- }
-
- // 发邮件
- WxAppinfo appinfo = appinfoService.getByAppId(appId);
- if (appinfo != null) {
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
-
- StringBuilder titleSB = new StringBuilder();
- if (appinfo.getType().equals(EnumAppType.C.getCode())) {
- titleSB.append("C端小程序");
- } else if (appinfo.getType().equals(EnumAppType.B.getCode())) {
- titleSB.append("B端小程序");
- } else if (appinfo.getType().equals(EnumAppType.MP_S.getCode())) {
- titleSB.append("公众号-服务号");
- } else if (appinfo.getType().equals(EnumAppType.MP_P.getCode())) {
- titleSB.append("公众号-订阅号");
- }
- titleSB.append(appinfo.getName());
- if (success) {
- titleSB.append("审核通过");
- } else {
- titleSB.append("审核未通过");
- }
-
- StringBuilder sb = new StringBuilder();
- sb.append(df.format(new Date())).append("\n");
- if (success) {
- sb.append("审核通过\n");
- } else {
- sb.append("审核未通过\n").append("原因").append(reason);
- }
-
- String[] receivers = new String[]{"wangmei@iformall.com", "wuguoqiang@iformall.com", "huanghui@iformall.com", "sunmingming@iformall.com"};
-
- //发送邮件
- mailService.sendSimpleMail(receivers, titleSB.toString(), sb.toString());
- }
- }
-
- @GetMapping(value = "/createOpenPlatform")
- @ApiOperation("创建微信开放平台")
- public ResultData createOpenPlatform(@RequestParam(value = "appId") String appId) {
- Gson gson = new GsonBuilder().create();
- try {
- String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).createOpenPlatform(appId);
- logger.info(responseStr);
- WxOpenPlatformResult openPlatformResult = gson.fromJson(responseStr, WxOpenPlatformResult.class);
- if (openPlatformResult.isSuccess()) {
- WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId);
- if (authorizerInfo != null) {
- authorizerInfo.setId(authorizerInfo.getId());
- authorizerInfo.setOpenAppid(openPlatformResult.getOpenAppid());
- authorizerInfoService.updateOpenAppid(authorizerInfo);
- }
- }
- return new ResultData(responseStr);
- } catch (WxErrorException e) {
- logger.error(e.getMessage());
- return new ResultData(Result.ERROR, e.getMessage());
- }
- }
-
- @GetMapping(value = "/bindOpenPlatform")
- @ApiOperation("绑定微信开放平台")
- public ResultData bindOpenPlatform(@RequestParam(value = "appId") String appId, @RequestParam(value = "openAppId") String openAppId) {
- Gson gson = new GsonBuilder().create();
- try {
- String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).bindOpenPlatform(appId, openAppId);
- logger.info(responseStr);
- WxOpenResult openResult = gson.fromJson(responseStr, WxOpenResult.class);
- if (openResult.isSuccess()) {
- return new ResultData();
- }
- return new ResultData(Result.ERROR, responseStr);
- } catch (WxErrorException e) {
- logger.error(e.getMessage());
- return new ResultData(Result.ERROR, e.getMessage());
- }
- }
-
- @GetMapping(value = "/unbindOpenPlatform")
- @ApiOperation("解绑微信开放平台")
- public ResultData unbindOpenPlatform(@RequestParam(value = "appId") String appId, @RequestParam(value = "openAppId") String openAppId) {
- Gson gson = new GsonBuilder().create();
- try {
- String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).unbindOpenPlatform(appId, openAppId);
- logger.info(responseStr);
- WxOpenResult openResult = gson.fromJson(responseStr, WxOpenResult.class);
- if (openResult.isSuccess()) {
- return new ResultData();
- }
- return new ResultData(Result.ERROR, responseStr);
- } catch (WxErrorException e) {
- logger.error(e.getMessage());
- return new ResultData(Result.ERROR, e.getMessage());
- }
- }
-
- @GetMapping(value = "/getOpenPlatform")
- @ApiOperation("获取微信开放平台appId")
- public ResultData getOpenPlatform(@RequestParam(value = "appId") String appId) {
- Gson gson = new GsonBuilder().create();
- try {
- String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getBindOpenPlatform(appId);
- logger.info(responseStr);
- WxOpenPlatformResult openPlatformResult = gson.fromJson(responseStr, WxOpenPlatformResult.class);
- if (openPlatformResult.isSuccess()) {
- return new ResultData(openPlatformResult.getOpenAppid());
- }
- return new ResultData(Result.ERROR, responseStr);
- } catch (WxErrorException e) {
- logger.error(e.getMessage());
- return new ResultData(Result.ERROR, e.getMessage());
- }
- }
-
- @GetMapping(value = "/clearQuota")
- @ApiOperation("代公众号清零quota,每个公众号每个月有10次清零机会,包括在微信公众平台上的清零以及调用API进行清零")
- public ResultData clearQuota(@RequestParam(value = "appId") String appId) {
- try {
- openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).clearQuota(appId);
- return new ResultData();
- } catch (WxErrorException e) {
- logger.error(e.getMessage());
- return new ResultData(Result.ERROR, e.getMessage());
- }
- }
- }
|