增加 获取微信小程序 URL SCHEME 接口

This commit is contained in:
Jack 2025-07-19 15:35:38 +08:00
parent b57d1dd0b4
commit 96cb0d6cc3
5 changed files with 156 additions and 4 deletions

View File

@ -266,7 +266,7 @@ public interface ShopService {
@PostMapping(value = "/admin/shop/mq-message/sendMqMsg")
CommonResult sendMqMsg(@RequestParam(name = "exchange") String exchange, @RequestParam(name = "routing_key") String routing_key, @RequestParam(name = "data") Object data);
@PostMapping(value = "/admin/wxqrcode/getWxQrCode")
@PostMapping(value = "/admin/shop/wxqrcode/getWxQrCode")
CommonResult getWxQrCode(@RequestParam(name = "path") String path, @RequestBody Map<String, Object> params);
@GetMapping(value = "/admin/shop/shopController/getWaitPayNum")

View File

@ -63,7 +63,6 @@ secure:
- "/**/*.png"
- "/**/*.ico"
- "/webjars/springfox-swagger-ui/**"
# - "/actuator/**"
- "/mall-auth/oauth/token"
- "/mall-auth/rsa/publicKey"
- "/admin/account/account-user-base/register"
@ -72,7 +71,6 @@ secure:
- "/shop/static/**"
- "/admin/account/open/**"
- "/admin/account/account-user-base/doLogin"
#- "/mobile/pay/index/lkl_wxPay_notify_url" #拉卡拉微信支付回调
- "/mobile/pay/index/notify_url"
- "/mobile/pay/index/return_url"
- "/admin/pay/pay-user-resource/userInfoImport"
@ -91,6 +89,7 @@ secure:
- "/shop/sync/third/**"
- "/esProduct/**"
- "/admin/oss/upload/**"
- "/admin/shop/wxqrcode/common/wxurlscheme"
- "/mobile/**/**/test/case"
- "/**/**/testcase"
universal:

View File

@ -7,6 +7,7 @@ import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.exception.ApiException;
import com.suisung.mall.common.utils.I18nUtil;
import com.suisung.mall.shop.wechat.service.WxQrCodeService;
import com.suisung.mall.shop.wechat.service.WxURLSchemeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
@ -16,12 +17,15 @@ import java.util.Map;
@Api(tags = "微信小程序码服务控制器")
@RestController
@RequestMapping("/admin/wxqrcode")
@RequestMapping("/admin/shop/wxqrcode")
public class WxQrCodeContorller {
@Autowired
private WxQrCodeService wxQrCodeService;
@Autowired
private WxURLSchemeService wxURLSchemeService;
@ApiOperation(value = "获取小程序码", notes = "获取小程序码")
@RequestMapping(value = "/getWxQrCode", method = RequestMethod.POST)
public CommonResult getWxQrCode(@RequestParam(value = "preparedUrl") String preparedUrl,
@ -40,4 +44,10 @@ public class WxQrCodeContorller {
return wxQrCodeService.genUnlimitedWxQrCode2(params.getStr("page"), params.getStr("scene"));
}
@ApiOperation(value = "生成小发同城小程序首页跳转 URL Scheme", notes = "生成小发同城小程序首页跳转 URL Scheme")
@PostMapping(value = "/common/wxurlscheme")
public CommonResult generateCommonWxUrlScheme() {
return wxURLSchemeService.generateCommonWxUrlScheme();
}
}

View File

@ -0,0 +1,17 @@
package com.suisung.mall.shop.wechat.service;
import com.suisung.mall.common.api.CommonResult;
/**
* 微信小程序 URL Scheme 跳转链接
*/
public interface WxURLSchemeService {
/**
* 生成小程序公共 URL Scheme 跳转链接 跳转到小发同城小程序首页 ( redis 缓存)
* 官方参考链接https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/url-scheme/generateScheme.html
*
* @return
*/
CommonResult generateCommonWxUrlScheme();
}

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
* Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
* Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
* Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
* Vestibulum commodo. Ut rhoncus gravida arcu.
*/
package com.suisung.mall.shop.wechat.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.suisung.mall.common.api.CommonResult;
import com.suisung.mall.common.utils.RestTemplateHttpUtil;
import com.suisung.mall.core.web.service.RedisService;
import com.suisung.mall.shop.wechat.service.WxURLSchemeService;
import com.suisung.mall.shop.wechat.utils.WxUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class WxURLSchemeServiceImpl implements WxURLSchemeService {
private final WxUtil wxUtil;
@Resource
private RedisService redisService;
public WxURLSchemeServiceImpl(WxUtil wxUtil) {
this.wxUtil = wxUtil;
}
/**
* 生成小程序公共 URL Scheme 跳转链接
* === 功能说明 ===
* 1. 优先从Redis缓存获取Scheme
* 2. 无缓存时调用微信API生成
* 3. 结果缓存30天
* === 技术实现 ===
* - 使用Redis缓存热点数据
* - 使用RestTemplate调用微信API
* - 采用TimeUnit计算时间间隔
*
* @return CommonResult 包含openlink的JSON对象
*/
@Override
public CommonResult generateCommonWxUrlScheme() {
// 常量定义
final String REDIS_KEY = "rdsCommonWxUrlScheme";
final long EXPIRE_DAYS = 30;
// === 第一阶段尝试从Redis获取缓存 ===
Object cachedScheme = redisService.get(REDIS_KEY);
if (cachedScheme != null) {
JSONObject result = new JSONObject();
result.put("openlink", cachedScheme);
return CommonResult.success(result);
}
// === 第二阶段构建微信API请求 ===
String accessToken;
try {
accessToken = wxUtil.getAccessToken(); // 获取微信access_token
} catch (Exception e) {
log.error("获取微信access_token失败", e);
return CommonResult.failed("系统繁忙,请稍后重试");
}
String apiUrl = "https://api.weixin.qq.com/wxa/generatescheme?access_token=" + accessToken;
// 请求头设置
Map<String, String> headers = new HashMap<>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json; charset=utf-8");
// 请求体构建
JSONObject requestBody = new JSONObject();
JSONObject jumpWxa = new JSONObject();
jumpWxa.put("path", "pages/index/index"); // 固定跳转路径
requestBody.put("jump_wxa", jumpWxa);
requestBody.put("is_expire", true);
requestBody.put("expire_type", 0);
long expireSeconds = TimeUnit.DAYS.toSeconds(EXPIRE_DAYS); // 30天有效期
requestBody.put("expire_time", System.currentTimeMillis() / 1000 + expireSeconds);
// === 第三阶段调用微信API ===
JSONObject wechatResponse;
try {
wechatResponse = RestTemplateHttpUtil.sendPost(apiUrl, headers, requestBody, JSONObject.class);
} catch (Exception e) {
log.error("调用微信生成URL Scheme API失败", e);
return CommonResult.failed("系统繁忙,请稍后重试");
}
// === 第四阶段处理微信响应 ===
if (wechatResponse == null || wechatResponse.getInt("errcode") != 0) {
String errorMsg = wechatResponse != null ?
wechatResponse.getStr("errmsg") : "微信接口无响应";
log.error("微信接口返回错误:{}", errorMsg);
return CommonResult.failed(errorMsg);
}
String openLink = wechatResponse.getStr("openlink");
if (StrUtil.isBlank(openLink)) {
log.error("微信返回的openlink为空");
return CommonResult.failed("微信返回数据异常");
}
// === 第五阶段缓存结果 ===
try {
redisService.set(REDIS_KEY, openLink, expireSeconds);
} catch (Exception e) {
log.error("Redis缓存失败", e);
// 缓存失败不影响主流程
}
JSONObject result = new JSONObject();
result.put("openlink", openLink);
return CommonResult.success(result);
}
}