生成会员码

This commit is contained in:
wangw 2025-03-12 16:43:21 +08:00
parent b5f08cfede
commit 3058f1c50f
4 changed files with 91 additions and 0 deletions

View File

@ -3,13 +3,21 @@ package com.czg.controller.admin;
import com.czg.account.dto.ShopActivateDTO; import com.czg.account.dto.ShopActivateDTO;
import com.czg.account.service.ShopActivateService; import com.czg.account.service.ShopActivateService;
import com.czg.annotation.SaAdminCheckPermission; import com.czg.annotation.SaAdminCheckPermission;
import com.czg.config.RedisCst;
import com.czg.exception.CzgException;
import com.czg.resp.CzgResult; import com.czg.resp.CzgResult;
import com.czg.sa.StpKit; import com.czg.sa.StpKit;
import com.czg.service.RedisService;
import com.czg.service.account.util.WechatAuthUtil;
import jakarta.annotation.Resource; 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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 店铺充值活动管理 * 店铺充值活动管理
@ -23,6 +31,10 @@ import java.util.List;
public class ShopActivateController { public class ShopActivateController {
@Resource @Resource
private ShopActivateService shopActivateService; private ShopActivateService shopActivateService;
@Resource
private RedisService redisService;
@Resource
private WechatAuthUtil wechatUtil;
/** /**
* 店铺充值活动列表 * 店铺充值活动列表
@ -54,4 +66,21 @@ public class ShopActivateController {
public CzgResult<Boolean> edit(@RequestBody @Validated ShopActivateDTO activateDTO) { public CzgResult<Boolean> edit(@RequestBody @Validated ShopActivateDTO activateDTO) {
return CzgResult.success(shopActivateService.edit(activateDTO)); return CzgResult.success(shopActivateService.edit(activateDTO));
} }
/**
* 获取会员码
* @param params shopId 必填
* env_version 存在即生成体验版
*/
@PostMapping("/getVipCode")
public CzgResult<Object> getVipCode(@RequestBody Map<String, Object> 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));
}
} }

View File

@ -29,6 +29,9 @@ public interface RedisCst {
//店铺取餐码key //店铺取餐码key
String SHOP_CODE = "shop:code:"; String SHOP_CODE = "shop:code:";
//店铺会员码Key 跳转会员页面
String SHOP_VIP_CODE = "shop:vip:code:";
// 排队取号全局号码 // 排队取号全局号码
String TABLE_CALL_NUMBER = "table:call:number:"; String TABLE_CALL_NUMBER = "table:call:number:";

View File

@ -17,6 +17,7 @@ public enum SysParamCodeEnum {
ALI_OSS_ACCESS_SECRET("ali_oss_access_secret", "阿里云oss_secret"), ALI_OSS_ACCESS_SECRET("ali_oss_access_secret", "阿里云oss_secret"),
ALI_OSS_ENDPOINT("ali_oss_endpoint", "阿里云endpoint"), ALI_OSS_ENDPOINT("ali_oss_endpoint", "阿里云endpoint"),
ALI_OSS_ROLE_ARN("ali_oss_role_arn", "阿里云roleArn"), ALI_OSS_ROLE_ARN("ali_oss_role_arn", "阿里云roleArn"),
WX_MINI_VIP_URL("wx_mini_vip_url", "小程序会员页面地址"),
; ;
private final String code; private final String code;

View File

@ -1,20 +1,28 @@
package com.czg.service.account.util; package com.czg.service.account.util;
import cn.hutool.core.codec.Base64; 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.core.util.StrUtil;
import cn.hutool.crypto.symmetric.AES; import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpUtil; import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.czg.config.RedisCst;
import com.czg.resp.CzgResult; import com.czg.resp.CzgResult;
import com.czg.service.RedisService;
import com.czg.system.dto.SysParamsDTO; import com.czg.system.dto.SysParamsDTO;
import com.czg.system.enums.SysParamCodeEnum;
import com.czg.system.service.SysParamsService; import com.czg.system.service.SysParamsService;
import com.google.gson.JsonObject;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@ -27,6 +35,10 @@ import java.util.Map;
public class WechatAuthUtil { public class WechatAuthUtil {
@DubboReference(check = false) @DubboReference(check = false)
private SysParamsService sysParamsService; private SysParamsService sysParamsService;
@Resource
private RedisService redisService;
@Resource
private AliOssUtil aliOssUtil;
// @Value("${wx.appId}") // @Value("${wx.appId}")
private String appId; private String appId;
@ -38,6 +50,9 @@ public class WechatAuthUtil {
// @Value("${wx.account.secrete}") // @Value("${wx.account.secrete}")
private String accountSecrete; 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<String, String> linkedHashMap = new LinkedHashMap<>(); static LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
@ -87,6 +102,49 @@ public class WechatAuthUtil {
return JSONObject.parseObject(resp).getString("openid"); 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<String, Object> 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<String, Object> 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) { public JSONObject getSession(String code) {
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session"; String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
Map<String, Object> requestUrlParam = new HashMap<>(); Map<String, Object> requestUrlParam = new HashMap<>();