package com.lp.controller; import com.lp.bo.UserInfoBO; import com.lp.cache.CacheName; import com.lp.cache.ProCacheUtil; import com.lp.cfg.ProConfig; import com.lp.common.Code; import com.lp.service.base.FileInfoService; import com.lp.util.LogUtil; import com.lp.util.LogUtil4j; import com.lp.util.ObjectUtil; import com.lp.util.ResultMapUtils; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.bean.WxMenu.WxMenuButton; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.util.StringUtils; import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; import me.chanjar.weixin.mp.api.WxMpMessageRouter; import me.chanjar.weixin.mp.api.WxMpServiceImpl; import me.chanjar.weixin.mp.bean.WxMpCustomMessage; import me.chanjar.weixin.mp.bean.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.bean.result.WxMpUser; 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 org.springframework.web.servlet.ModelAndView; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @Controller public class WxMpController extends BaseController { @Resource(name = "wxMpService") private WxMpServiceImpl wxMpService; @Resource(name = "wxMpMessageRouter") private WxMpMessageRouter wxMpMessageRouter; @Autowired private WxMpInMemoryConfigStorage wxMpConfigStorage; protected final static Logger LOGGER = LoggerFactory.getLogger(WxMpController.class); /** * 微信消息 和事件推送 * * @param signature * @param timestamp * @param nonce * @param echostr * @param req * @param response * @throws IOException */ @RequestMapping(method = RequestMethod.GET, value = "weixin/mp/msg") public void verifyMsg(@RequestParam(value = "signature", required = false) String signature, @RequestParam(value = "timestamp", required = false) String timestamp, @RequestParam(value = "nonce", required = false) String nonce, @RequestParam(value = "echostr", required = false) String echostr, HttpServletRequest req, HttpServletResponse response) throws IOException { LogUtil4j.debugLogger.debug("get echostr with {}", echostr); PrintWriter out = response.getWriter(); out.write(echostr); out.flush(); } /** * 微信消息 和事件推送 * * @param req * @param response * @throws IOException */ @RequestMapping(method = RequestMethod.POST, value = "weixin/mp/msg") public void rcvMsg(HttpServletRequest req, HttpServletResponse response) throws Exception { WxMpXmlMessage msg = WxMpXmlMessage.fromXml(req.getInputStream()); // 事件 if (WxConsts.XML_MSG_EVENT.equals(msg.getMsgType())) { // subscribe(订阅) 、 unsubscribe(取消订阅) if ("subscribe".equals(msg.getEvent())) { // 给用户发送含有绑定url的消息通知 String user_open_id = msg.getFromUserName(); WxMpCustomMessage ms = new WxMpCustomMessage(); ms.setToUser(user_open_id); ms.setMsgType("text"); ms.setContent("欢迎关注"+ ProConfig.PROJECT_NAME +"公众号服务平台!"); wxMpService.customMessageSend(ms); // 发送图文消息 } else if ("unsubscribe".equals(msg.getEvent())) { // 取消订阅 } }else if(WxConsts.XML_MSG_TEXT.equals(msg.getMsgType()) ){ // 文字消息 }else if(WxConsts.XML_MSG_IMAGE.equals(msg.getMsgType()) ){ // 图片消息 } } /** * 创建微信菜单 * * @param req * @param response * @throws IOException * @throws WxErrorException */ @RequestMapping(method = RequestMethod.GET, value = "weixin/mp/menu/create") public void menuCreate(HttpServletRequest req, HttpServletResponse response) throws IOException, WxErrorException { LogUtil4j.debugLogger.debug("------------------+++++++++++++++++ menuCreate"); PrintWriter out = response.getWriter(); response.setCharacterEncoding("UTF-8"); createMenu(out); out.write("menu create OK!"); out.flush(); } /** * 微信网页授权回调接口 * * @param req * @param response * @param state * @param code * @throws IOException * @throws WxErrorException */ @RequestMapping(method = RequestMethod.GET, value = "oauth2/authorize/weixin/mp") public String authCallback(HttpServletRequest req, HttpServletResponse response, @RequestParam(required = false) String state, @RequestParam(required = false) String code) throws IOException, WxErrorException { LogUtil4j.debugLogger.debug("------------------+++++++++++++++++ authCallback called with {}---{}", state, code); if (!StringUtils.isEmpty(code)) { // 通过code换取网页授权access_token WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code); // --- String openid = wxMpOAuth2AccessToken.getOpenId(); // 设置到session中 req.getSession().setAttribute("open_id", openid); LogUtil4j.debugLogger.debug("------------------+++++++++++++++++ authCallback get openid {}", openid); if(state.contains("cbind")){ WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, "zh_CN"); LogUtil4j.debugLogger.debug("------------------+++++++++++++++++ authCallback get wxMpUser {}", wxMpUser); // 联系人信息绑定 UserInfoBO userx = new UserInfoBO() ; userx.setWx_open_id(openid); if( wxMpUser.getHeadImgUrl().length() > 190 ){ userx.setWx_img_url(wxMpUser.getHeadImgUrl()); }else{ // 设置默认图片 userx.setWx_img_url(ProConfig.LOCAL_DOMAIN +"/image/oss/iot/default.jpg" ); } req.getSession().setAttribute("user", userx); // 这个session 时间设置的短一点 req.getSession().setMaxInactiveInterval(30); return "redirect:" + state.replace("*", "&"); } UserInfoBO user = ProCacheUtil.getCache(CacheName.USERINFO_OPENID, openid); if( ObjectUtil.isEmpty(user) ){ // 获取用户更多的信息,snap_userinfo 授权 WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, "zh_CN"); LogUtil4j.debugLogger.debug("------------------+++++++++++++++++ authCallback get wxMpUser {}", wxMpUser); if( state.contains("bind") ){ // 账户绑定,将微信或者url if(wxMpUser.getHeadImgUrl().length() < 180){ req.getSession().setAttribute("wximg", wxMpUser.getHeadImgUrl()); } req.getSession().setAttribute("nickname", wxMpUser.getNickname()); // 跳转到绑定页面 return "redirect:/service/wiot/bind" ; } } // 账户已存在,则不做处理 req.getSession().setAttribute("user", user); } return "redirect:" + state.replace("*", "&"); } /** * 创建菜单 * * @throws WxErrorException * @throws UnsupportedEncodingException * test: * http://chen.sub.testlg.com/lpro/service/weixin/mp/menu/create */ public String createMenu(PrintWriter out) throws WxErrorException, UnsupportedEncodingException { String ret_msg = null; // 初始化菜单 WxMenu wxMenu = new WxMenu(); // 微信一级菜单列表 List menuList = new ArrayList(); String url = ProConfig.LOCAL_DOMAIN ; generateWeixinMenu(menuList, Arrays.asList("实时监控", url+ "/service/wiot/scene"), null); generateWeixinMenu(menuList, Arrays.asList("报警管理", url+ "/service/wiot/alarm"), null); generateWeixinMenu(menuList, Arrays.asList("个人信息") , Arrays.asList( Arrays.asList("项目信息",url+ "/service/wiot/mscene"), Arrays.asList("设备配网",url+ "/service/wiot/deviceConfigwifi") )); wxMenu.setButtons(menuList); wxMpService.menuCreate(wxMenu); return ret_msg; } /** * 工具类 * @param menuList * @param parent * @param sub */ private void generateWeixinMenu(List menuList,List parent,List> sub ){ WxMenuButton parentMenu = new WxMenuButton(); if(parent.size() >1){ parentMenu.setName(parent.get(0)); parentMenu.setType("view"); parentMenu.setUrl(parent.get(1)); }else{ parentMenu.setName(parent.get(0)); parentMenu.setType("view"); List secordBtns = new ArrayList(); for(int i=0; i< sub.size();i++){ WxMenuButton askBtn = new WxMenuButton(); askBtn.setName(sub.get(i).get(0)); askBtn.setType("view"); askBtn.setUrl(sub.get(i).get(1)); secordBtns.add(askBtn); } parentMenu.setSubButtons(secordBtns); } menuList.add(parentMenu); } @Autowired private FileInfoService fileInfoService ; /** * 将提交到微信文件下载并提交到服务器 * * @param req * @param resp * @return */ @RequestMapping(method = RequestMethod.GET, value = "/wx/media/{media_id}") public ModelAndView getWxMediaInfo(HttpServletRequest req, HttpServletResponse resp, @RequestHeader(value = ResultMapUtils.USER_KEY, required = true) String userKey, @PathVariable String media_id) { // media_id为附件上传到微信平台的id Map resultMap = getResultMap(); try { UserInfoBO user = getUserInfoByUserKey(userKey) ; if(ObjectUtil.isNotEmpty(user)){ resultMap = fileInfoService.downFileImgFromWxServer(wxMpConfigStorage.getAccessToken(), media_id, user.getId()); }else{ putStatusCode(resultMap, Code.ResponseCode.SystemCode.NO_AUTHORIZATION); } } catch (Exception e) { putStatusCode(resultMap, Code.ResponseCode.SystemCode.ERROR); LogUtil.errorLog(e.getMessage()); } return getModelAndView(resp, resultMap); } /** * 发送临时图片消息 * * @param open_id * @param content */ public void sendWxMpCustomTempImageMessage(String wx_open_id, String imagePath, String title) { InputStream inputStream = null; try { File imageFile = new File(imagePath); inputStream = new FileInputStream(imageFile); byte b[] = new byte[(int) imageFile.length()]; // 创建合适文件大小的数组 inputStream.read(b); // 读取文件中的内容到b[]数组 // 上传临时图片 WxMediaUploadResult wxMediaUploadResult = wxMpService.mediaUpload(WxConsts.CUSTOM_MSG_IMAGE, "jpg", inputStream); // 发送图片消息 WxMpCustomMessage wm = new WxMpCustomMessage(); wm.setToUser(wx_open_id); wm.setMsgType(WxConsts.CUSTOM_MSG_IMAGE); // wm.setToUser("from " + wx_open_id); wm.setMediaId(wxMediaUploadResult.getMediaId()); wxMpService.customMessageSend(wm); } catch (Exception e) { LogUtil.errorLog(e.getMessage()); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }