package com.cweb.controller; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.binarywang.wx.miniapp.bean.WxMaUserInfo; import com.alibaba.fastjson.JSONObject; import com.cweb.config.SessionKeyCache; import com.cweb.config.SysConst; import com.cweb.config.WxMaConfiguration; import com.hai.common.exception.ErrorCode; import com.hai.common.exception.ErrorHelp; import com.hai.common.exception.SysCode; import com.hai.common.security.SessionObject; import com.hai.common.security.UserCenter; import com.hai.common.utils.HttpsUtils; import com.hai.common.utils.ResponseMsgUtil; import com.hai.entity.HighUser; import com.hai.model.HighUserModel; import com.hai.model.ResponseData; import com.hai.service.HighUserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; 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.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.net.URLEncoder; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @Controller @RequestMapping(value = "/wechat") @Api(value = "微信授权") public class WechatController { private static final Logger log = LoggerFactory.getLogger(WechatController.class); @Autowired private UserCenter userCenter; @Resource private HighUserService highUserService; @RequestMapping(value = "/handleCode", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "小程序code解析") public ResponseData compairCode(@RequestParam(value = "code", required = true) String code, HttpServletRequest request, HttpServletResponse response) { try { //校验code,openId不能同时为空 if (StringUtils.isEmpty(code)) { throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.REQ_PARAMS_ERROR, ""); } //请求微信api,获取用户session_key以及openId final WxMaService wxService = WxMaConfiguration.getMaService(); WxMaJscode2SessionResult session = wxService.jsCode2SessionInfo(code); //保存小程序用户登录的openId及sessionKey信息 SessionKeyCache.setData(session.getOpenid(), session.getSessionKey(), -1); JSONObject jo = new JSONObject(); jo.put("openId", session.getOpenid()); return ResponseMsgUtil.success(jo); } catch (Exception e) { return ResponseMsgUtil.exception(e); } } @RequestMapping(value = "/login", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "小程序授权用户登录接口") public ResponseData login(@RequestParam(value = "openId", required = true) String openId, HttpServletRequest request, HttpServletResponse response) { try { //校验code,openId不能同时为空 if (StringUtils.isEmpty(openId)) { throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.REQ_PARAMS_ERROR, ""); } HighUser highUser = highUserService.findByOpenId(openId); if (highUser == null) { log.error("login error!", "未找到用户"); throw ErrorHelp.genException(SysCode.System, ErrorCode.UN_MEMBER_ERROR, ""); } // 定义个人所有数据 HighUserModel loginDataModel = new HighUserModel(); highUser.setPassword(null); loginDataModel.setHighUser(highUser); SessionObject so = new SessionObject(openId, 99 , loginDataModel); userCenter.save(request, response, so); return ResponseMsgUtil.success(so); } catch (Exception e) { return ResponseMsgUtil.exception(e); } } @RequestMapping(value = "/getPhoneNumber", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "小程序获取用户手机号码") public ResponseData getPhoneNumber(@RequestParam(value = "encryptedData", required = true) String encryptedData, @RequestParam(value = "iv", required = true) String iv, @RequestParam(value = "openId", required = true) String openId, HttpServletRequest request, HttpServletResponse response) { try { log.error("origin encryptedData:" + encryptedData + ";iv:" + iv); //校验openId不能为空 //encryptedData,iv与unionId不能同时为空 encryptedData = encryptedData.replace(" ", "+"); iv = iv.replace(" ", "+"); log.error("dest encryptedData:" + encryptedData + ";iv:" + iv); if (StringUtils.isEmpty(openId) || StringUtils.isEmpty(encryptedData) || StringUtils.isEmpty(iv)) { throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.REQ_PARAMS_ERROR, ""); } //请求微信api,获取用户session_key以及openId String sessionKey = SessionKeyCache.getData(openId); final WxMaService wxService = WxMaConfiguration.getMaService(); WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv); if (phoneNoInfo == null || StringUtils.isEmpty(phoneNoInfo.getPurePhoneNumber())) { throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.WECHAT_DECRYPT_ERROR, "用户phoneNumber解析失败"); } HighUser user = highUserService.findByOpenId(openId); if (user == null) { user = new HighUser(); user.setOpenId(openId); user.setRegTime(new Date()); user.setStatus(1); user.setGold(0); user.setPhone(phoneNoInfo.getPurePhoneNumber()); highUserService.insertUser(user); } else { user.setPhone(phoneNoInfo.getPurePhoneNumber()); highUserService.updateUser(user); } // 定义个人所有数据 HighUserModel highUserModel = new HighUserModel(); user.setPassword(null); highUserModel.setHighUser(user); SessionObject so = new SessionObject(openId, 1 , highUserModel); userCenter.save(request, response, so); return ResponseMsgUtil.success(so); } catch (Exception e) { return ResponseMsgUtil.exception(e); } } @RequestMapping(value = "/getUserInfo", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "小程序获取用户信息") public ResponseData getUserInfo(@RequestParam(value = "encryptedData", required = true) String encryptedData, @RequestParam(value = "iv", required = true) String iv, @RequestParam(value = "openId", required = true) String openId, HttpServletRequest request, HttpServletResponse response) { try { //校验openId不能为空 //encryptedData,iv与unionId不能同时为空 encryptedData = encryptedData.replace(" ", "+"); iv = iv.replace(" ", "+"); if (StringUtils.isEmpty(openId) || StringUtils.isEmpty(encryptedData) || StringUtils.isEmpty(iv)) { throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.REQ_PARAMS_ERROR, ""); } //请求微信api,获取用户session_key以及openId String sessionKey = SessionKeyCache.getData(openId); final WxMaService wxService = WxMaConfiguration.getMaService(); WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv); System.out.println(""); if (userInfo == null) { throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.WECHAT_DECRYPT_ERROR, "用户phoneNumber解析失败"); } HighUser user = highUserService.findByOpenId(openId); if (user == null) { user = new HighUser(); user.setOpenId(openId); user.setRegTime(new Date()); user.setStatus(1); user.setGold(0); user.setHeaderImg(userInfo.getAvatarUrl()); user.setName(userInfo.getNickName()); highUserService.insertUser(user); } else { user.setHeaderImg(userInfo.getAvatarUrl()); user.setName(userInfo.getNickName()); highUserService.updateUser(user); } // 定义个人所有数据 HighUserModel highUserModel = new HighUserModel(); user.setPassword(null); highUserModel.setHighUser(user); SessionObject so = new SessionObject(openId, 1 , highUserModel); userCenter.save(request, response, so); return ResponseMsgUtil.success(so); } catch (Exception e) { return ResponseMsgUtil.exception(e); } } @RequestMapping(value = "/getH5Code", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "【H5】获取Code") public ResponseData getH5Code() { try { Map params = new LinkedHashMap<>(); params.put("appid", SysConst.getSysConfig().getWxH5AppId()); params.put("redirect_uri", URLEncoder.encode("https://hsgcs.dctpay.com/H5/index.html#/", "utf-8")); //params.put("redirect_uri", "https://hsgcs.dctpay.com/H5/index.html#/"); params.put("response_type", "code"); params.put("scope", "snsapi_userinfo"); params.put("state", "STATE"); String apiUrl = "https://open.weixin.qq.com/connect/oauth2/authorize"; StringBuffer param = new StringBuffer(); int i = 0; for (String key : params.keySet()) { if (i == 0) param.append("?"); else param.append("&"); param.append(key).append("=").append(params.get(key)); i++; } apiUrl += param + "#wechat_redirect"; return ResponseMsgUtil.success(apiUrl); } catch (Exception e) { return ResponseMsgUtil.exception(e); } } @RequestMapping(value = "/getH5AccessToken", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "【H5】获取AccessToken") public ResponseData getH5AccessToken(@RequestParam(value = "code", required = true) String code) { try { Map params = new HashMap<>(); params.put("appid", SysConst.getSysConfig().getWxH5AppId()); params.put("secret", SysConst.getSysConfig().getWxH5AppSecret()); params.put("code", code); params.put("grant_type", "authorization_code"); return ResponseMsgUtil.success(HttpsUtils.doGet("https://api.weixin.qq.com/sns/oauth2/access_token", params)); } catch (Exception e) { return ResponseMsgUtil.exception(e); } } @RequestMapping(value = "/getH5UserInfo", method = RequestMethod.GET) @ResponseBody @ApiOperation(value = "【H5】获取用户信息") public ResponseData getH5UserInfo(@RequestParam(value = "code", required = true) String code, HttpServletRequest request, HttpServletResponse response) { try { // 获取access_token Map params = new HashMap<>(); params.put("appid", SysConst.getSysConfig().getWxH5AppId()); params.put("secret", SysConst.getSysConfig().getWxH5AppSecret()); params.put("code", code); params.put("grant_type", "authorization_code"); JSONObject jsonObject = HttpsUtils.doGet("https://api.weixin.qq.com/sns/oauth2/access_token", params); String accessToken = jsonObject.getString("access_token"); String openid = jsonObject.getString("openid"); if (StringUtils.isBlank(accessToken) || StringUtils.isBlank(openid)) { log.error("getH5UserInfo error!", "获取微信access_token失败" ); throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "获取微信access_token失败"); } params.clear(); params.put("access_token", accessToken); params.put("openid", openid); params.put("lang", "zh_CN"); JSONObject userInfo = HttpsUtils.doGet("https://api.weixin.qq.com/sns/userinfo", params); System.out.println(userInfo.toJSONString()); if (StringUtils.isNotBlank(userInfo.getString("errcode"))) { log.error("getH5UserInfo error!", "获取微信用户信息失败"); throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "获取微信用户信息失败"); } HighUser user = highUserService.findByOpenId(openid); if (user == null) { user = new HighUser(); user.setOpenId(openid); user.setRegTime(new Date()); user.setStatus(1); user.setGold(0); user.setHeaderImg(userInfo.getString("headimgurl")); user.setName(userInfo.getString("nickname")); highUserService.insertUser(user); } else { user.setHeaderImg(userInfo.getString("headimgurl")); user.setName(userInfo.getString("nickname")); highUserService.updateUser(user); } // 定义个人所有数据 HighUserModel highUserModel = new HighUserModel(); user.setPassword(null); highUserModel.setHighUser(user); SessionObject so = new SessionObject(openid, 1 , highUserModel); userCenter.save(request, response, so); return ResponseMsgUtil.success(so); } catch (Exception e) { return ResponseMsgUtil.exception(e); } } }