|
|
@@ -0,0 +1,192 @@
|
|
|
+package org.springblade.wx.controller;
|
|
|
+
|
|
|
+import cn.hutool.core.lang.Assert;
|
|
|
+import cn.hutool.crypto.Mode;
|
|
|
+import cn.hutool.crypto.Padding;
|
|
|
+import cn.hutool.crypto.symmetric.AES;
|
|
|
+import cn.hutool.http.Header;
|
|
|
+import cn.hutool.http.HttpRequest;
|
|
|
+import cn.hutool.http.HttpResponse;
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springblade.core.oss.model.BladeFile;
|
|
|
+import org.springblade.core.tool.api.R;
|
|
|
+import org.springblade.core.tool.utils.StringUtil;
|
|
|
+import org.springblade.modules.resource.builder.oss.OssBuilder;
|
|
|
+import org.springblade.wx.config.ConfigForClient;
|
|
|
+import org.springblade.wx.constant.MiniProgramType;
|
|
|
+import org.springblade.wx.constant.WeChatApi;
|
|
|
+import org.springblade.wx.dto.DataDto;
|
|
|
+import org.springblade.wx.dto.JumpWxa;
|
|
|
+import org.springblade.wx.dto.SchemeDto;
|
|
|
+import org.springblade.wx.service.WeChatService;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
+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 java.io.ByteArrayInputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.util.Base64;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author cy-computer
|
|
|
+ */
|
|
|
+@RestController
|
|
|
+@Slf4j
|
|
|
+@RequestMapping("/wx-app")
|
|
|
+@Api(tags = "微信小程序登录模块")
|
|
|
+@AllArgsConstructor
|
|
|
+public class WxAppController {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对象存储构建类
|
|
|
+ */
|
|
|
+ private final OssBuilder ossBuilder;
|
|
|
+
|
|
|
+ private ConfigForClient configForClient;
|
|
|
+ private StringRedisTemplate stringRedisTemplate;
|
|
|
+ private WeChatService weChatService;
|
|
|
+
|
|
|
+
|
|
|
+ private static final String ACCESS_TOKEN = "access_token:";
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("获取开发数据")
|
|
|
+ @PostMapping("/getOpenData")
|
|
|
+ public R getOpenData(@RequestBody DataDto dataDto) {
|
|
|
+ byte[] key = Base64.getDecoder().decode(dataDto.getSessionKey().replaceAll(" ", "+"));
|
|
|
+ byte[] iv = Base64.getDecoder().decode(dataDto.getIv().replaceAll(" ", "+"));
|
|
|
+ byte[] content = Base64.getDecoder().decode(dataDto.getEncryptedData().replaceAll(" ", "+"));
|
|
|
+ AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key, iv);
|
|
|
+ return R.data(new String(aes.decrypt(content)));
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("获取小程序码")
|
|
|
+ @GetMapping("/getCode")
|
|
|
+ public R getCode(String scene,MiniProgramType type,String page) throws IOException {
|
|
|
+ HttpResponse unlimitCode = weChatService.getUnlimitCode(scene, type, page);
|
|
|
+ byte[] bytes = unlimitCode.bodyBytes();
|
|
|
+ BladeFile bladeFile = this.uploadImage(bytes);
|
|
|
+ return R.data(bladeFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("获取access_token")
|
|
|
+ @GetMapping("/getAccessToken")
|
|
|
+ public R getAccessTokenOfClient() {
|
|
|
+
|
|
|
+ String appId = configForClient.getAppId();
|
|
|
+ String appSecret = configForClient.getAppSecret();
|
|
|
+ String accessTokenKey = ACCESS_TOKEN + appId;
|
|
|
+ //从缓存中获取
|
|
|
+ String accessToken = stringRedisTemplate.opsForValue().get(accessTokenKey);
|
|
|
+ if (StringUtil.isBlank(accessToken)) {
|
|
|
+ StringBuilder sb = new StringBuilder("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=");
|
|
|
+ sb.append(appId).append("&secret=").append(appSecret);
|
|
|
+ String url = sb.toString();
|
|
|
+ String s = HttpUtil.get(url);
|
|
|
+ JSONObject jsonObject = JSON.parseObject(s);
|
|
|
+ accessToken = jsonObject.getString("access_token");
|
|
|
+ if (StringUtil.isNotBlank(accessToken)) {
|
|
|
+ stringRedisTemplate.opsForValue().set(accessTokenKey, accessToken, 7000, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return R.data(accessToken);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("获取GenerateScheme")
|
|
|
+ @GetMapping("/getGenerateScheme")
|
|
|
+ public R getGenerateScheme(String path, String query) {
|
|
|
+ SchemeDto schemeDto = new SchemeDto();
|
|
|
+ schemeDto.setJump_wxa(new JumpWxa(path,query));
|
|
|
+ String accessToken = (String)this.getAccessTokenOfClient().getData();
|
|
|
+ String url = "https://api.weixin.qq.com/wxa/generatescheme?access_token=" + accessToken;
|
|
|
+
|
|
|
+ String s = HttpRequest.post(url)
|
|
|
+ .header(Header.CONTENT_TYPE, "application/json")
|
|
|
+ .body(JSON.toJSONString(schemeDto))
|
|
|
+ .execute().body();
|
|
|
+ JSONObject jsonObject = JSON.parseObject(s);
|
|
|
+ return R.data(jsonObject);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation("获取openId")
|
|
|
+ @GetMapping("/getOpenId")
|
|
|
+ public R getOpenId(String code,String type) {
|
|
|
+ //默认获取C端的openId
|
|
|
+ if (StringUtil.isBlank(type)) {
|
|
|
+ type = "CLIENT";
|
|
|
+ }
|
|
|
+ return R.data(weChatService.getOpenId(code, MiniProgramType.valueOf(type)));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("获取小程序码")
|
|
|
+ @GetMapping("/createWxaQrCode")
|
|
|
+ public R createWxaQrCode(String path,@RequestParam String type) throws IOException {
|
|
|
+ //根据类型获取accessToken
|
|
|
+ String accessToken = weChatService.fetchAccessToken(MiniProgramType.valueOf(type));
|
|
|
+ Assert.notNull(accessToken, "获取accessToken失败");
|
|
|
+
|
|
|
+ String url = WeChatApi.createWxaQrCode.buildUrl(accessToken);
|
|
|
+ RestTemplate rest = new RestTemplate();
|
|
|
+
|
|
|
+
|
|
|
+ Map<String,Object> param = new HashMap<>(4);
|
|
|
+ param.put("path", path);
|
|
|
+ param.put("width", 430);
|
|
|
+
|
|
|
+ MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
|
|
+ HttpEntity requestEntity = new HttpEntity(param, headers);
|
|
|
+ ResponseEntity<byte[]> entity = rest.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
|
|
|
+ log.info("调用小程序生成微信永久二维码URL接口返回结果:" + entity.getBody());
|
|
|
+
|
|
|
+ byte[] result = entity.getBody();
|
|
|
+ BladeFile bladeFile = this.uploadImage(result);
|
|
|
+ return R.data(bladeFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ private BladeFile uploadImage(byte[] bytes) throws IOException {
|
|
|
+ BladeFile bladeFile = new BladeFile();
|
|
|
+
|
|
|
+ InputStream inputStream = null;
|
|
|
+ try {
|
|
|
+ inputStream = new ByteArrayInputStream(bytes);
|
|
|
+ MultipartFile multipartFile =new MockMultipartFile("file", "shopQrCode.jpg", "text/plain", inputStream);
|
|
|
+ //上传到对象存储
|
|
|
+ bladeFile = ossBuilder.template().putFile(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }finally {
|
|
|
+ if (inputStream != null) {
|
|
|
+ inputStream.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return bladeFile;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String replaceEnter(String str){
|
|
|
+ String reg ="[\n-\r]";
|
|
|
+ Pattern p = Pattern.compile(reg);
|
|
|
+ Matcher m = p.matcher(str);
|
|
|
+ return m.replaceAll("");
|
|
|
+ }
|
|
|
+
|
|
|
+}
|