From 3058f1c50f3a8f8ba283b5be45dc95404f496a9e Mon Sep 17 00:00:00 2001 From: wangw <1594593906@qq.com> Date: Wed, 12 Mar 2025 16:43:21 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E6=88=90=E4=BC=9A=E5=91=98=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/ShopActivateController.java | 29 ++++++++++ .../main/java/com/czg/config/RedisCst.java | 3 + .../czg/system/enums/SysParamCodeEnum.java | 1 + .../service/account/util/WechatAuthUtil.java | 58 +++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopActivateController.java b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopActivateController.java index 704f6f7e..3701b3c1 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopActivateController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/admin/ShopActivateController.java @@ -3,13 +3,21 @@ package com.czg.controller.admin; import com.czg.account.dto.ShopActivateDTO; import com.czg.account.service.ShopActivateService; import com.czg.annotation.SaAdminCheckPermission; +import com.czg.config.RedisCst; +import com.czg.exception.CzgException; import com.czg.resp.CzgResult; import com.czg.sa.StpKit; +import com.czg.service.RedisService; +import com.czg.service.account.util.WechatAuthUtil; import jakarta.annotation.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.util.CollectionUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; /** * 店铺充值活动管理 @@ -23,6 +31,10 @@ import java.util.List; public class ShopActivateController { @Resource private ShopActivateService shopActivateService; + @Resource + private RedisService redisService; + @Resource + private WechatAuthUtil wechatUtil; /** * 店铺充值活动列表 @@ -54,4 +66,21 @@ public class ShopActivateController { public CzgResult edit(@RequestBody @Validated ShopActivateDTO activateDTO) { return CzgResult.success(shopActivateService.edit(activateDTO)); } + + /** + * 获取会员码 + * @param params shopId 必填 + * env_version 存在即生成体验版 + */ + @PostMapping("/getVipCode") + public CzgResult getVipCode(@RequestBody Map params) throws Exception { + if (CollectionUtils.isEmpty(params) || !params.containsKey("shopId")) { + throw new CzgException("参数错误"); + } + String redisKey = RedisCst.SHOP_VIP_CODE + params.get("shopId"); + if (redisService.hasKey(redisKey)) { + return CzgResult.success(redisService.get(redisKey)); + } + return CzgResult.success(wechatUtil.getFetchQrCode(params)); + } } diff --git a/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java b/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java index 4f57a0ab..8a05631f 100644 --- a/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java +++ b/cash-common/cash-common-redis/src/main/java/com/czg/config/RedisCst.java @@ -29,6 +29,9 @@ public interface RedisCst { //店铺取餐码key String SHOP_CODE = "shop:code:"; + //店铺会员码Key 跳转会员页面 + String SHOP_VIP_CODE = "shop:vip:code:"; + // 排队取号全局号码 String TABLE_CALL_NUMBER = "table:call:number:"; diff --git a/cash-common/cash-common-service/src/main/java/com/czg/system/enums/SysParamCodeEnum.java b/cash-common/cash-common-service/src/main/java/com/czg/system/enums/SysParamCodeEnum.java index 3b8d6152..17f9f077 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/system/enums/SysParamCodeEnum.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/system/enums/SysParamCodeEnum.java @@ -17,6 +17,7 @@ public enum SysParamCodeEnum { ALI_OSS_ACCESS_SECRET("ali_oss_access_secret", "阿里云oss_secret"), ALI_OSS_ENDPOINT("ali_oss_endpoint", "阿里云endpoint"), ALI_OSS_ROLE_ARN("ali_oss_role_arn", "阿里云roleArn"), + WX_MINI_VIP_URL("wx_mini_vip_url", "小程序会员页面地址"), ; private final String code; diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java b/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java index 17fef0e7..cffe2a8f 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java @@ -1,20 +1,28 @@ package com.czg.service.account.util; import cn.hutool.core.codec.Base64; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.symmetric.AES; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; +import com.czg.config.RedisCst; import com.czg.resp.CzgResult; +import com.czg.service.RedisService; import com.czg.system.dto.SysParamsDTO; +import com.czg.system.enums.SysParamCodeEnum; import com.czg.system.service.SysParamsService; +import com.google.gson.JsonObject; import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; import jakarta.validation.constraints.NotBlank; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Component; +import java.io.InputStream; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -27,6 +35,10 @@ import java.util.Map; public class WechatAuthUtil { @DubboReference(check = false) private SysParamsService sysParamsService; + @Resource + private RedisService redisService; + @Resource + private AliOssUtil aliOssUtil; // @Value("${wx.appId}") private String appId; @@ -38,6 +50,9 @@ public class WechatAuthUtil { // @Value("${wx.account.secrete}") private String accountSecrete; + private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token"; + private static final String QR_CODE_URL = "https://api.weixin.qq.com/wxa/getwxacode"; + static LinkedHashMap linkedHashMap = new LinkedHashMap<>(); @@ -87,6 +102,49 @@ public class WechatAuthUtil { return JSONObject.parseObject(resp).getString("openid"); } + //获取小程序token + private String getAccessToken() { + String url = String.format("%s?grant_type=client_credential&appid=%s&secret=%s", TOKEN_URL, appId, secrete); + String response = HttpUtil.get(url); + com.alibaba.fastjson.JSONObject jsonResponse = com.alibaba.fastjson.JSONObject.parseObject(response); + if (!jsonResponse.containsKey("access_token")) { + throw new RuntimeException("Failed to retrieve access token: " + response); + } + return jsonResponse.getString("access_token"); + } + + /** + * 生成 小程序码 跳转对应页面 + * + * @param params + * @return + */ + public String getFetchQrCode(Map params) throws Exception { + String url = aliOssUtil.upload(fetchQrCode(params), aliOssUtil.getPath("shopVip", "png")); + redisService.set(RedisCst.SHOP_VIP_CODE + params.get("shopId"), url); + return url; + } + + //生成页面地址 + private InputStream fetchQrCode(Map params) { + JsonObject jsonObject = new JsonObject(); + //路径 + jsonObject.addProperty("path", STR."\{sysParamsService.getSysParamValue(SysParamCodeEnum.WX_MINI_VIP_URL.getCode())}?shopId=\{params.get("shopId")}"); + //是否需要透明底色,为 true 时,生成透明底色的小程序码 + jsonObject.addProperty("is_hyaline", true); + //正式版为 release,体验版为 trial,开发版为 develop + if (params.containsKey("env_version")) { + jsonObject.addProperty("env_version", "trial"); + } + String accessToken = getAccessToken(); + String url = String.format("%s?access_token=%s", QR_CODE_URL, accessToken); + return HttpUtil.createPost(url) + .body(jsonObject.toString(), "application/json") + .execute() + .bodyStream(); + } + + public JSONObject getSession(String code) { String requestUrl = "https://api.weixin.qq.com/sns/jscode2session"; Map requestUrlParam = new HashMap<>();