提交修改

This commit is contained in:
quyixiao 2025-11-12 12:32:31 +08:00
parent c4b1253fb3
commit 55c5cd7335
9 changed files with 292 additions and 96 deletions

View File

@ -0,0 +1,177 @@
package com.heyu.api.data.utils;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.heyu.api.data.dto.AccessTokenDTO;
import com.heyu.api.data.dto.WeiChatLoginDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
@Slf4j
@Component
public class WeChatUtils {
/**
* 微信 auth.code2Session 接口
*/
public final static String WECHAT_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
public final static String WECHAT_APPID = "wx75fa59c097bd3dfd";
public final static String WECHAT_SECRET = "1837c382de696013a2dfc64591e6b854";
public static final String wechatAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?appid=%s&secret=%s&grant_type=client_credential";
private static final String linkUrl = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=";
private static final String schemeUrl = "https://api.weixin.qq.com/wxa/generatescheme?access_token=";
@Autowired
private RedisUtils redisUtils;
@Value("${eb.config.weixin.pay.appid}")
private String appid;
@Value("${eb.config.weixin.pay.appSecret}")
private String appSecret;
public static final String jsapi_acessToken = "jsapi_acessToken";
public static void main(String[] args) {
// 获取 openid
// WeiChatLoginDTO weiChatLoginDTO = getOpenId("0b1tMGll2jJdBg4sfwml2pnGk32tMGlg",WECHAT_APPID,WECHAT_SECRET);
// System.out.println(weiChatLoginDTO.getOpenid());
// System.out.println("o6t1512tT-JuBeT6rIu6RhFGf3BQ".length());
// System.out.println("FMOMCp63WoRFUJtL4tvjcQ==".length());
}
/**
* 通过微信登录code获取openId
*
* @param code 微信登录code
* @return openId
*/
// ============json============{"session_key":"FMOMCp63WoRFUJtL4tvjcQ==","openid":"o6t1512tT-JuBeT6rIu6RhFGf3BQ"}
public WeiChatLoginDTO getOpenId(String code) {
try {
// 添加参数
HashMap<String, String> map = new HashMap<>();
map.put("appid", appid);
map.put("secret", appSecret);
map.put("js_code", code);
map.put("grant_type", "authorization_code");
// 使用封装好的HttpClientUtil工具类发送请求
String result = HttpUtils.doGet(WECHAT_LOGIN_URL, map);
log.info("getOpenId params:{}, result:{}", JSON.toJSONString(map), result);
// 将JSON字符串转换为JSONObject对象
WeiChatLoginDTO weiChatLoginDTO = JSON.parseObject(result, WeiChatLoginDTO.class);
// 从JSONObject中获取openid并返回
return weiChatLoginDTO;
} catch (Exception e) {
log.error("getOpenId error", e);
}
return null;
}
public AccessTokenDTO getAccessTokenDTO() {
AccessTokenDTO accessTokenDTO = null;
String acessTokenJson = redisUtils.get(jsapi_acessToken);
if (StringUtils.isNotEmpty(acessTokenJson)) {
accessTokenDTO = JSONObject.parseObject(acessTokenJson, AccessTokenDTO.class);
} else {
accessTokenDTO = getAccessToken(appid, appSecret);
redisUtils.set(jsapi_acessToken, JSON.toJSONString(accessTokenDTO), RedisUtils.one_hours);
}
return accessTokenDTO;
}
// 获取access_token
private AccessTokenDTO getAccessToken(String appid, String appSecret) {
String url = String.format(wechatAccessTokenUrl, appid, appSecret);
String responseBody = HttpUtils.doGet(url);
log.info("getAccessToken responseBody:{}", responseBody);
AccessTokenDTO accessTokenDTO = JSONObject.parseObject(responseBody, AccessTokenDTO.class);
return accessTokenDTO;
}
/**
* 生成小程序跳转短链 code
* https://blog.csdn.net/weixin_44548582/article/details/131868367
* <p>
* https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-link/generateUrlLink.html
*
* @param path 小程序页面路径 null为首页
* @param query 与前端商量携带的参数
* @return
*/
public String jumpAppletShortUrl(String path, String query, Integer days) {
String accessToken = getAccessTokenDTO().getAccessToken();
String url = linkUrl + accessToken;
cn.hutool.json.JSONObject body = cn.hutool.json.JSONUtil.createObj();
body.putOpt("path", path);
body.putOpt("query", query);
//链接过期类型0时间戳 1间隔天数
body.putOpt("expire_type", 1);
//指定失效天数最多30
days = (days == null || days > 30) ? 30 : days;
body.putOpt("expire_interval", days);
//小程序版本正式版为 "release"体验版为"trial"开发版为"develop"
body.putOpt("env_version", "trial");
String result = HttpUtil.post(url, body.toJSONString(2));
log.info("jumpAppletShortUrl params:{}, result:{}", JSON.toJSONString(body), result);
return result;
}
/**
* scheme 跳转微信小程序需中转H5
*
* @param path
* @param query
* @param days https://blog.csdn.net/weixin_44548582/article/details/131868367
*
* https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-scheme/generateScheme.html
* @return
*/
public String jumpAppletSchemeUrl(String path, String query, Integer days) {
String url = schemeUrl + getAccessTokenDTO().getAccessToken();
cn.hutool.json.JSONObject body = cn.hutool.json.JSONUtil.createObj();
cn.hutool.json.JSONObject jumpWxa = cn.hutool.json.JSONUtil.createObj();
jumpWxa.putOpt("path", path);
jumpWxa.putOpt("query", query);
jumpWxa.putOpt("env_version", "release");
body.putOpt("jump_wxa", jumpWxa);
//链接过期类型0时间戳 1间隔天数
body.putOpt("expire_type", 1);
body.putOpt("is_expire", true);
//指定失效天数最多30
days = (days == null || days > 30) ? 30 : days;
body.putOpt("expire_interval", days);
String post = HttpUtil.post(url, body.toJSONString(2));
log.info("jumpAppletSchemeUrl params:{}, result:{}", JSON.toJSONString(body), post);
cn.hutool.json.JSONObject result = cn.hutool.json.JSONUtil.parseObj(post);
return result.toJSONString(2);
}
}

View File

@ -1,56 +0,0 @@
package com.heyu.api.data.utils;
import com.alibaba.fastjson.JSON;
import com.heyu.api.data.dto.WeiChatLoginDTO;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
@Slf4j
public class WechatUtils {
/**
* 微信 auth.code2Session 接口
*/
public final static String WECHAT_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
public final static String WECHAT_APPID = "wx75fa59c097bd3dfd";
public final static String WECHAT_SECRET = "1837c382de696013a2dfc64591e6b854";
public static void main(String[] args) {
// 获取 openid
WeiChatLoginDTO weiChatLoginDTO = getOpenId("0b1tMGll2jJdBg4sfwml2pnGk32tMGlg");
System.out.println(weiChatLoginDTO.getOpenid());
System.out.println("o6t1512tT-JuBeT6rIu6RhFGf3BQ".length());
System.out.println("FMOMCp63WoRFUJtL4tvjcQ==".length());
}
/**
* 通过微信登录code获取openId
*
* @param code 微信登录code
* @return openId
*/
// ============json============{"session_key":"FMOMCp63WoRFUJtL4tvjcQ==","openid":"o6t1512tT-JuBeT6rIu6RhFGf3BQ"}
public static WeiChatLoginDTO getOpenId(String code) {
try {
// 添加参数
HashMap<String, String> map = new HashMap<>();
map.put("appid", WECHAT_APPID);
map.put("secret", WECHAT_SECRET);
map.put("js_code", code);
map.put("grant_type", "authorization_code");
// 使用封装好的HttpClientUtil工具类发送请求
String json = HttpUtils.doGet(WECHAT_LOGIN_URL, map);
System.out.println("============json============" + json);
// 将JSON字符串转换为JSONObject对象
WeiChatLoginDTO weiChatLoginDTO = JSON.parseObject(json, WeiChatLoginDTO.class);
// 从JSONObject中获取openid并返回
return weiChatLoginDTO;
} catch (Exception e) {
log.error("getOpenId error", e);
}
return null;
}
}

View File

@ -0,0 +1,11 @@
package com.heyu.api.alibaba.request.vv;
import lombok.Data;
@Data
public class AppLinkRequest extends AppBaseRequest {
}

View File

@ -0,0 +1,10 @@
package com.heyu.api.alibaba.request.vv;
import lombok.Data;
@Data
public class AppQrCodeRequest extends AppBaseRequest {
}

View File

@ -0,0 +1,11 @@
package com.heyu.api.alibaba.request.vv;
import lombok.Data;
@Data
public class AppSchemeRequest extends AppBaseRequest {
}

View File

@ -0,0 +1,55 @@
package com.heyu.api.controller.vv;
import com.heyu.api.alibaba.request.vv.AppLinkRequest;
import com.heyu.api.alibaba.request.vv.AppSchemeRequest;
import com.heyu.api.common.annotation.Describe;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.WeChatUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping("/app/create")
public class AppLinkController {
// 自行配置正式版为 "release"体验版为 "trial"开发版为 "develop"默认是正式版
private String envVersion = "trial";
@Autowired
private WeChatUtils weChatUtils;
/***
* 链接
* http://localhost:8888/app/create/link
*
*/
@Describe("生成link")
@RequestMapping("/link")
public R link(@RequestBody AppLinkRequest request) {
String url = weChatUtils.jumpAppletShortUrl("abc", "89ew8392", 30);
return R.ok();
}
/***
* 链接
* http://localhost:8888/app/create/scheme
*/
@Describe("生成")
@RequestMapping("/scheme")
public R scheme(@RequestBody AppSchemeRequest request) {
String url = weChatUtils.jumpAppletSchemeUrl("abc", "89ew8392", 30);
return R.ok();
}
}

View File

@ -1,15 +1,12 @@
package com.heyu.api.controller.vv; package com.heyu.api.controller.vv;
import com.alibaba.fastjson.JSON; import com.heyu.api.alibaba.request.vv.AppQrCodeRequest;
import com.alibaba.fastjson.JSONObject;
import com.heyu.api.alibaba.request.vv.AppPromoterRequest;
import com.heyu.api.common.annotation.Describe; import com.heyu.api.common.annotation.Describe;
import com.heyu.api.data.dto.AccessTokenDTO; import com.heyu.api.data.dto.AccessTokenDTO;
import com.heyu.api.data.utils.HttpUtils; import com.heyu.api.data.utils.HttpUtils;
import com.heyu.api.data.utils.R; import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.RedisUtils; import com.heyu.api.data.utils.WeChatUtils;
import com.heyu.api.data.utils.StringUtils;
import com.heyu.api.oss.OssFileUploadService; import com.heyu.api.oss.OssFileUploadService;
import com.heyu.api.oss.OssUploadResult; import com.heyu.api.oss.OssUploadResult;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -26,30 +23,21 @@ import java.util.Map;
@RestController @RestController
@RequestMapping("/app/qrcode") @RequestMapping("/app/qrcode")
public class AppQrCodeController { public class AppQrCodeController {
public static final String wechatQrcodeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="; public static final String wechatQrcodeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";
public static final String wechatAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?appid=%s&secret=%s&grant_type=client_credential";
@Value("${eb.config.weixin.pay.appid}")
private String appid;
@Value("${eb.config.weixin.pay.appSecret}")
private String appSecret;
// 自行配置正式版为 "release"体验版为 "trial"开发版为 "develop"默认是正式版 // 自行配置正式版为 "release"体验版为 "trial"开发版为 "develop"默认是正式版
private String envVersion = "trial"; private String envVersion = "trial";
@Autowired
private RedisUtils redisUtils;
public static final String jsapi_acessToken = "jsapi_acessToken";
@Autowired @Autowired
private OssFileUploadService ossFileUploadService; private OssFileUploadService ossFileUploadService;
@Autowired
private WeChatUtils weChatUtils;
/*** /***
* 列表 * 列表
* http://localhost:8888/app/qrcode/create * http://localhost:8888/app/qrcode/create
@ -59,20 +47,14 @@ public class AppQrCodeController {
*/ */
@Describe("生成二维码") @Describe("生成二维码")
@RequestMapping("/create") @RequestMapping("/create")
public R create(@RequestBody AppPromoterRequest request) { public R create(@RequestBody AppQrCodeRequest request) {
AccessTokenDTO accessTokenDTO = weChatUtils.getAccessTokenDTO();
// 当前登录账号 // 当前登录账号
String accountId = "123456"; String accountId = "123456";
AccessTokenDTO accessTokenDTO = null;
String acessTokenJson = redisUtils.get(jsapi_acessToken);
if (StringUtils.isNotEmpty(acessTokenJson)) {
accessTokenDTO = JSONObject.parseObject(acessTokenJson, AccessTokenDTO.class);
} else {
accessTokenDTO = getAccessToken(appid, appSecret);
redisUtils.set(jsapi_acessToken, JSON.toJSONString(accessTokenDTO), RedisUtils.one_hours);
}
String accessToken = accessTokenDTO.getAccessToken();
String url = wechatQrcodeUrl + accessToken; String url = wechatQrcodeUrl + accessTokenDTO.getAccessToken();
Map<String, Object> body = new HashMap<>(); Map<String, Object> body = new HashMap<>();
@ -82,7 +64,6 @@ public class AppQrCodeController {
body.put("env_version", envVersion); body.put("env_version", envVersion);
// body.put("page", envVersion); 默认是主页页面 page例如 pages/index/index根路径前不要填加 /不能携带参数参数请放在scene字段里如果不填写这个字段默认跳主页面scancode_time为系统保留参数不允许配置 // body.put("page", envVersion); 默认是主页页面 page例如 pages/index/index根路径前不要填加 /不能携带参数参数请放在scene字段里如果不填写这个字段默认跳主页面scancode_time为系统保留参数不允许配置
// 透明 // 透明
body.put("is_hyaline", true); // 默认是false是否需要透明底色 true 生成透明底色的小程序 body.put("is_hyaline", true); // 默认是false是否需要透明底色 true 生成透明底色的小程序
@ -91,23 +72,16 @@ public class AppQrCodeController {
if (bytes == null) { if (bytes == null) {
return R.error("bytes is null"); return R.error("bytes is null");
} }
String error = new String(bytes); String error = new String(bytes);
if (error.contains("errcode")) { if (error.contains("errcode")) {
return R.error(error); return R.error(error);
} }
OssUploadResult ossUploadResult = ossFileUploadService.uploadImageByBytes(bytes); OssUploadResult ossUploadResult = ossFileUploadService.uploadImageByBytes(bytes);
return R.ok().setData(ossUploadResult); return R.ok().setData(ossUploadResult);
} }
// 获取access_token
public AccessTokenDTO getAccessToken(String appid, String appSecret) {
String url = String.format(wechatAccessTokenUrl, appid, appSecret);
String responseBody = HttpUtils.doGet(url);
log.info("getAccessToken responseBody:{}", responseBody);
AccessTokenDTO accessTokenDTO = JSONObject.parseObject(responseBody, AccessTokenDTO.class);
return accessTokenDTO;
}
} }

View File

@ -34,11 +34,16 @@ public class AppUserLoginController {
private RedisUtils redisUtils; private RedisUtils redisUtils;
@Autowired
private WeChatUtils weChatUtils;
// http://localhost:8888/app/user/login // http://localhost:8888/app/user/login
@RequestMapping("/login") @RequestMapping("/login")
@Describe("微信用户登录") @Describe("微信用户登录")
public R login(@RequestBody AppUserLoginRequest request) { public R login(@RequestBody AppUserLoginRequest request) {
WeiChatLoginDTO weiChatLoginDTO = WechatUtils.getOpenId(request.getCode()); WeiChatLoginDTO weiChatLoginDTO = weChatUtils.getOpenId(request.getCode());
if (weiChatLoginDTO == null) { if (weiChatLoginDTO == null) {
return R.error("code 失效"); return R.error("code 失效");
} }

View File

@ -91,6 +91,15 @@
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version> <!-- Use the latest stable version -->
</dependency>
<!-- SpringBoot 拦截器 --> <!-- SpringBoot 拦截器 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>