嗨森逛服务
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hai-server/hai-cweb/src/main/java/com/cweb/controller/WechatController.java

288 lines
13 KiB

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.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
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.IDGenerator;
import com.hai.common.utils.RedisUtil;
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.HighUserPayPasswordService;
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.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;
@Controller
@RequestMapping(value = "/wechat")
@Api(value = "微信授权")
public class WechatController {
private static final Logger log = LoggerFactory.getLogger(WechatController.class);
private static final String WX_OPENID_SESSION_REDIS = "WX_OPENID_SESSION_REDIS";
@Autowired
private UserCenter userCenter;
@Resource
private HighUserService highUserService;
@Resource
private HighUserPayPasswordService highUserPayPasswordService;
@Resource
private RedisUtil redisUtil;
@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信息
redisUtil.hset(WX_OPENID_SESSION_REDIS,session.getOpenid(),session);
JSONObject jo = new JSONObject();
jo.put("openId", session.getOpenid());
return ResponseMsgUtil.success(jo);
} catch (Exception e) {
return ResponseMsgUtil.exception(e);
}
}
@RequestMapping(value = "/loginByPhone", method = RequestMethod.GET)
@ResponseBody
@ApiOperation(value = "小程序根据手机号登录或注册")
public ResponseData loginByPhone(@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
Object skObject = redisUtil.hget(WX_OPENID_SESSION_REDIS, openId);
if (skObject == null){
throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.WECHAT_LOGIN_ERROR);
}
WxMaJscode2SessionResult session = (WxMaJscode2SessionResult)skObject;
final WxMaService wxService = WxMaConfiguration.getMaService();
WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), encryptedData, iv);
if (phoneNoInfo == null || StringUtils.isEmpty(phoneNoInfo.getPurePhoneNumber())) {
throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.WECHAT_DECRYPT_ERROR, "用户phoneNumber解析失败");
}
// 根据手机号查询用户
HighUser user = highUserService.findByPhone(phoneNoInfo.getPurePhoneNumber());
if (user == null) {
user = new HighUser();
user.setName("用户" + IDGenerator.nextId(5));
user.setPhone(phoneNoInfo.getPurePhoneNumber());
user.setRegTime(new Date());
user.setGold(0);
user.setOpenId(session.getOpenid());
user.setUnionId(session.getUnionid());
user.setStatus(1);
// 用户信息完整状态
// 0:完整
// 1:需要填写用户信息
// 2:需要填写手机号
user.setInfoCompleteStatus(1);
highUserService.insertUser(user);
} else {
if (session.getOpenid() == null) {
user.setOpenId(session.getOpenid());
user.setUnionId(session.getUnionid());
highUserService.updateUser(user);
}
}
// 定义个人所有数据
HighUserModel highUserModel = new HighUserModel();
HighUser detailData = highUserService.getDetailDataByUser(user.getId());
detailData.setPassword(null);
highUserModel.setHighUser(detailData);
SessionObject so = new SessionObject(user.getPhone(), 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 {
// 用户
SessionObject sessionObject = userCenter.getSessionObject(request);
HighUserModel userInfoModel = (HighUserModel) sessionObject.getObject();
//校验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
Object skObject = redisUtil.hget(WX_OPENID_SESSION_REDIS,openId);
if (skObject == null){
throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.WECHAT_LOGIN_ERROR);
}
WxMaJscode2SessionResult session = (WxMaJscode2SessionResult)skObject;
final WxMaService wxService = WxMaConfiguration.getMaService();
WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(session.getSessionKey(), encryptedData, iv);
if (userInfo == null) {
throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.WECHAT_DECRYPT_ERROR, "用户phoneNumber解析失败");
}
HighUser user = highUserService.findByUserId(userInfoModel.getHighUser().getId());
if (user == null) {
throw ErrorHelp.genException(SysCode.MiniProgram, ErrorCode.COMMON_ERROR, "未找到用户信息");
}
// 用户信息完整状态
// 0:完整
// 1:需要填写用户信息
// 2:需要填写手机号
if (user.getInfoCompleteStatus() == 1) {
if (StringUtils.isNotBlank(user.getPhone())) {
user.setInfoCompleteStatus(0);
} else {
user.setInfoCompleteStatus(2);
}
}
user.setName(userInfo.getNickName());
user.setHeaderImg(userInfo.getAvatarUrl());
highUserService.updateUser(user);
// 定义个人所有数据
HighUserModel highUserModel = new HighUserModel();
HighUser detailData = highUserService.getDetailDataByUser(user.getId());
detailData.setPassword(null);
highUserModel.setHighUser(detailData);
if (user.getPhone() == null) {
log.error("login error!", "未绑定手机号");
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未绑定手机号");
}
SessionObject so = new SessionObject(user.getPhone(), 1 , highUserModel);
userCenter.save(request, response, so);
return ResponseMsgUtil.success(so);
} 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<String, Object> 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 = "/loginByTel", method = RequestMethod.POST)
@ResponseBody
@ApiOperation(value = "根据手机号码登陆")
public ResponseData loginByTel(@RequestBody JSONObject body,
HttpServletRequest request, HttpServletResponse response) {
try {
if (body == null
|| StringUtils.isBlank(body.getString("phone"))
|| StringUtils.isBlank(body.getString("smsCode"))) {
throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
}
// 根据手机号查询用户
HighUser user = highUserService.findByPhone(body.getString("phone"));
// 获取手机号验证码
String phoneSmsCode = (String) redisUtil.get("SMS_"+ body.getString("phone"));
// 验证码校验
if (StringUtils.isNotBlank(phoneSmsCode) && Objects.equals(phoneSmsCode,body.getString("smsCode"))) {
// 定义个人所有数据
// 定义个人所有数据
HighUserModel highUserModel = new HighUserModel();
HighUser detailData = highUserService.getDetailDataByUser(user.getId());
detailData.setPassword(null);
highUserModel.setHighUser(detailData);
SessionObject so = new SessionObject(user.getPhone(), 1 , highUserModel);
userCenter.save(request, response, so);
return ResponseMsgUtil.success(so);
}
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "验证码错误");
} catch (Exception e) {
return ResponseMsgUtil.exception(e);
}
}
}