package com.ylx.web.controller.massage; 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 cn.hutool.core.net.url.UrlBuilder; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ylx.common.annotation.Log; import com.ylx.common.constant.Constants; import com.ylx.common.core.controller.BaseController; import com.ylx.common.core.domain.AjaxResult; import com.ylx.common.core.domain.R; import com.ylx.common.core.domain.model.WxLoginUser; import com.ylx.common.enums.BusinessType; import com.ylx.framework.web.service.WxTokenService; import com.ylx.massage.utils.LocationUtil; import com.ylx.massage.utils.WxQrCodeUtil; import com.ylx.massage.utils.WxUtil; import com.ylx.massage.domain.TWxUser; import com.ylx.massage.service.TWxUserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author : YJR * @className : WxController * @description : [描述说明该类的功能] * @createTime : 2023/6/27 19:44 */ @RestController @Api(tags = {"微信"}) @RequestMapping("/wx") @Slf4j public class WxController extends BaseController { @Resource private WxUtil wxUtil; @Resource private WxQrCodeUtil wxQrCodeUtil; @Resource private TWxUserService wxUserService; @Resource private WxTokenService wxTokenService; @Autowired private WxMaService wxMaService; /** * 获取二维码 * * @param param * @return */ @ApiOperation("获取二维码") @RequestMapping(value = "getwxQrCode", method = RequestMethod.POST) public String getWxQrCodeUtil(@RequestBody JSONObject param) { String cOpenId = param.getString("cOpenId"); return wxQrCodeUtil.getWxQrcode(cOpenId); } /** * 小程序登录 * * @param wxLoginUser * @return */ @PostMapping("v0/login") @ApiOperation("小程序登录不用") public AjaxResult login(@RequestBody WxLoginUser wxLoginUser) { AjaxResult ajax = new AjaxResult(); try { // 验证输入数据的合法性 if (wxLoginUser == null || wxLoginUser.getCode() == null || wxLoginUser.getCode().isEmpty()) { return AjaxResult.error("输入数据不合法"); } //todo 获取用户信息自测方法 WxLoginUser wxUser = wxUtil.getUserOpenId(wxLoginUser.getCode()); if (wxUser == null) { return AjaxResult.error("获取用户信息失败"); } // 生成并返回令牌 String token = wxTokenService.createToken(wxUser); if (token == null || token.isEmpty()) { return AjaxResult.error("生成令牌失败"); } ajax.put(Constants.TOKEN, token); return ajax; } catch (Exception e) { // 捕获并处理异常,返回友好的错误信息 JSONObject errorObj = new JSONObject(); errorObj.put("message", "操作失败"); errorObj.put("error", e.getMessage()); return AjaxResult.error(JSON.toJSONString(errorObj)); } } /** * 获取电话号 * * @param param * @return */ @ApiOperation("获取电话号") @RequestMapping(value = "getPhone", method = RequestMethod.POST) public R getPhone(@RequestBody JSONObject param) { String code = param.getString("code"); String openId = param.getString("openId"); if (StringUtils.isBlank(code)) { return R.fail("openId或者授权conde为空"); } String phone = wxUtil.getUserPhone(openId, code); if (StringUtils.isBlank(phone)) { return R.fail("获取手机号信息失败,请重试"); } return R.ok(phone); } /** * 获取用户信息 * * @param * @return */ @ApiOperation("获取用户信息") @RequestMapping(value = "getUserInfo", method = RequestMethod.GET) public R getUserInfo() { WxLoginUser wxLoginUser = getWxLoginUser(); // 检查wxLoginUser是否为null if (wxLoginUser == null) { return R.fail("用户登录信息不存在"); } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() .eq(TWxUser::getcOpenid, wxLoginUser.getCOpenid()); TWxUser wxUser; try { wxUser = wxUserService.getOne(queryWrapper); } catch (Exception e) { log.error("获取用户信息失败", e); return R.fail("获取用户信息失败,系统异常"); } if (wxUser == null) { return R.fail("用户信息不存在"); } // 移除用户登录的session key wxUser.setcSessionKey(null); return R.ok(wxUser); } /** * 获取用户信息 * * @param param * @return */ @RequestMapping(value = "getUser", method = RequestMethod.POST) public List getUser(@RequestBody JSONObject param) { QueryWrapper wrapper = new QueryWrapper<>(); return wxUserService.list(wrapper); } @RequestMapping(value = "select", method = RequestMethod.GET) public R select(Page page, TWxUser user) { LambdaQueryWrapper objectLambdaQueryWrapper = new LambdaQueryWrapper<>(); objectLambdaQueryWrapper.eq(StringUtils.isNotBlank(user.getcOpenid()), TWxUser::getcOpenid, user.getcOpenid()). like(StringUtils.isNotBlank(user.getcNickName()), TWxUser::getcNickName, user.getcNickName()); // 获取查询返回结果 Page pageSelect = wxUserService.page(page, objectLambdaQueryWrapper); return R.ok(pageSelect); } /** * 登录接口 */ @ApiOperation("小程序登录") @Log(title = "小程序登录", businessType = BusinessType.OTHER) @PostMapping("/login") public R login(@RequestParam("code") String code, @RequestParam("encryptedData") String encryptedData, @RequestParam("iv") String iv) { try { // 调用微信 API 获取用户的 openid 和 session_key WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code); String openid = session.getOpenid(); // 调用微信 API 获取用户的手机号 WxMaPhoneNumberInfo phoneInfo = wxMaService.getUserService().getPhoneNoInfo(session.getSessionKey(), encryptedData, iv); String phoneNumber = phoneInfo.getPhoneNumber(); // 调用微信 API 获取用户的详细信息 WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(session.getSessionKey(),encryptedData,iv); // 获取用户昵称 String nickName = userInfo.getNickName(); // 获取用户头像 String avatarUrl = userInfo.getAvatarUrl(); // 获取用户国家 String country = userInfo.getCountry(); // 获取用户省份 String province = userInfo.getProvince(); // 获取用户城市 String city = userInfo.getCity(); // 将用户信息保存到数据库中 LambdaQueryWrapper objectLambdaQueryWrapper = new LambdaQueryWrapper<>(); objectLambdaQueryWrapper.eq(TWxUser::getcOpenid,openid); TWxUser user = wxUserService.getOne(objectLambdaQueryWrapper); if (user == null) { user = new TWxUser(); user.setcOpenid(openid); user.setcNickName(nickName); user.setcIcon(avatarUrl); user.setcPhone(phoneNumber); wxUserService.save(user); user.setId(user.getId()); } WxLoginUser wxUser = new WxLoginUser(); BeanUtils.copyProperties(user, wxUser); // 生成并返回令牌 String token = wxTokenService.createToken(wxUser); if (token == null || token.isEmpty()) { return R.fail("生成令牌失败"); } wxUser.setToken(token); // 返回用户信息 return R.ok(wxUser); } catch (WxErrorException e) { log.error("登录失败:" + e.getMessage(), e); return R.fail("登录失败:" + e.getMessage()); } } /** * 更新用户信息接口 */ @PostMapping("/update") public R updateUserInfo(@RequestBody TWxUser user) { try { // 前端校验后,再次进行后端的基础校验 if (user == null || user.getcOpenid() == null || user.getcOpenid().isEmpty()) { return R.fail("用户信息不能为空"); } // 保存或更新用户信息 if (wxUserService.saveOrUpdate(user)) { return R.ok("用户信息更新成功"); } else { return R.fail("更新用户信息失败"); } } catch (Exception e) { // 异常处理,记录日志并返回友好的错误信息 log.error("更新用户信息异常", e); return R.fail("更新用户信息异常,请稍后尝试"); } } /** * 获取微信用户手机号 * * @param code code值 */ public String getMobilePhoneByWeixin(String code) { try { String accessToken = wxMaService.getAccessToken(); String url = UrlBuilder .of("https://api.weixin.qq.com/wxa/business/getuserphonenumber") .addQuery("access_token", accessToken) .build(); Map paramBody = new HashMap<>(2); paramBody.put("code", code); String result = HttpUtil.post(url, JSON.toJSONString(paramBody)); JSONObject jsonObject = JSONObject.from(JSON.parseObject(result)); if ("40029".equals(jsonObject.getString("errcode"))) { throw new RuntimeException("code无效"); } if ("-1".equals(jsonObject.getString("errcode"))) { throw new RuntimeException("微信系统繁忙"); } JSONObject phoneInfo = jsonObject.getJSONObject("phone_info"); return phoneInfo.getString("phoneNumber"); } catch (WxErrorException e) { e.printStackTrace(); throw new RuntimeException("获取手机号失败"); } } }