package com.ruoyi.account.controller; import com.alibaba.fastjson.JSONObject; import com.alipay.api.internal.util.codec.Base64; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.account.api.model.TAppUser; import com.ruoyi.account.service.TAppUserService; import com.ruoyi.account.wx.body.resp.Code2SessionRespBody; import com.ruoyi.account.wx.body.resq.Code2SessionResqBody; import com.ruoyi.account.wx.model.WeixinProperties; import com.ruoyi.account.wx.pojo.AppletUserDecodeData; import com.ruoyi.account.wx.pojo.AppletUserEncrypteData; import com.ruoyi.account.wx.tools.WxAppletTools; import com.ruoyi.account.wx.tools.WxUtils; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.FileUploadUtils; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.redis.service.RedisService; import com.ruoyi.common.security.service.TokenService; import com.ruoyi.system.api.model.LoginUserApplet; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; //import org.springframework.mock.web.MockMultipartFile; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; import java.text.SimpleDateFormat; import java.util.*; /** *

* 微信小程序登录 前端控制器 *

* * @author xiaochen * @since 2024-08-06 */ @Slf4j @RestController @RequestMapping("/wxLogin") public class WxLoginController { @Autowired private TAppUserService appUserService; @Autowired private WeixinProperties wxConfig; @Autowired private RestTemplate wxRestTemplate; @Resource private RedisService redisService; /** * 上传文件存储在本地的根路径 */ @Value("${file.upload.location}") private String localFilePath; @ApiOperation(value = "通过code获得openid,获取用户信息",tags = {"微信小程序登录"}) @PostMapping("/openIdByJsCode") public AjaxResult> openIdByJsCode(@RequestBody AppletUserEncrypteData data) { log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", data.getCode()); WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisService); Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(data.getCode())); String openid = body.getOpenid(); String sessionKey = body.getSessionKey(); // 用户信息解密 数据验签 // if (StringUtils.isNotBlank(data.getSignature())) { // WxUtils.verifySignature(data.getRawData(), sessionKey, data.getSignature()); // } if(StringUtils.isEmpty(data.getEncryptedData()) || StringUtils.isEmpty(data.getIv())){ return AjaxResult.success("已拒绝授权"); } AppletUserDecodeData appletUserDecodeData = WxUtils.encryptedData(data.getEncryptedData(), sessionKey, data.getIv()); appletUserDecodeData.setOpenId(openid); return AjaxResult.success(appUserService.wxLogin(appletUserDecodeData,data.getInviteUserId())); } /** * 测试用 * @param appletUserDecodeData * @return */ @ApiOperation(value = "通过code获得openid,获取用户信息",tags = {"微信小程序登录"}) @PostMapping("/openIdByJsCodeTest") public AjaxResult> openIdByJsCode(@RequestBody AppletUserDecodeData appletUserDecodeData) { return AjaxResult.success(appUserService.wxLogin(appletUserDecodeData, null)); } // public static MultipartFile convertInputStreamToMultipartFile(InputStream inputStream, String fileName, String contentType) throws IOException { // return new MockMultipartFile(fileName, fileName, contentType, inputStream); // } @ApiOperation(value = "获取微信小程序二维码",tags = {"获取微信小程序二维码"}) @PostMapping("/getQRCode") public AjaxResult getQRCode() { InputStream inputStream = null; OutputStream outputStream = null; WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisService); String accessToken = appletTools.getAccessToken(""); try { String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accessToken; Map param = new HashMap<>(); // param.put("page", "pageA/houseDetail"); param.put("check_path", false); param.put("env_version", "trial"); param.put("width", 200); //二维码尺寸 param.put("is_hyaline", true); // 是否需要透明底色, is_hyaline 为true时,生成透明底色的小程序码 参数仅对小程序码生效 param.put("auto_color", true); // 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调 参数仅对小程序码生效 Map line_color = new HashMap<>(); line_color.put("r", 0); line_color.put("g", 0); line_color.put("b", 0); param.put("line_color", line_color); System.err.println("调用生成微信URL接口传参:" + param); MultiValueMap headers = new LinkedMultiValueMap<>(); HttpEntity requestEntity = new HttpEntity(param, headers); ResponseEntity entity = wxRestTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]); System.err.println("调用小程序生成微信永久小程序码URL接口返回结果:" + entity.getBody()); byte[] result = entity.getBody(); System.err.println(Base64.encodeBase64String(result)); inputStream = new ByteArrayInputStream(result); String finalFileName = System.currentTimeMillis() + "" + new SecureRandom().nextInt(0x0400) + ".jpeg"; // MultipartFile multipartFile = convertInputStreamToMultipartFile(inputStream, finalFileName, "image/jpeg"); // String name = FileUploadUtils.upload(localFilePath, multipartFile); // System.err.println(name); return AjaxResult.success(null); } catch (Exception e) { System.err.println("调用小程序生成微信永久小程序码URL接口异常" + e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return AjaxResult.success(); } /** * 获取微信token * @return */ @PostMapping("/getWXToken") public R getWXToken(){ WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisService); String accessToken = appletTools.getAccessToken(""); return R.ok(accessToken); } }