公众号订阅 用户

This commit is contained in:
2025-10-20 14:55:06 +08:00
parent 2b286e6a07
commit e0fc346f26
7 changed files with 233 additions and 5 deletions

View File

@@ -20,12 +20,17 @@ import com.czg.exception.ApiNotPrintException;
import com.czg.exception.CzgException;
import com.czg.sa.MyStpLogic;
import com.czg.sa.StpKit;
import com.czg.service.account.util.AcAccountUtil;
import com.czg.service.account.util.AlipayUtil;
import com.czg.service.account.util.WechatAuthUtil;
import com.czg.system.enums.SysParamCodeEnum;
import com.czg.system.service.SysParamsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* @author Administrator
@@ -36,9 +41,13 @@ public class UserAuthorizationServiceImpl implements UserAuthorizationService {
@Resource
private WechatAuthUtil wechatAuthUtil;
@Resource
private AcAccountUtil acAccountUtil;
@Resource
private AlipayUtil alipayUtil;
@Resource
private UserInfoService userInfoService;
@DubboReference
private SysParamsService paramsService;
@Override
public String getOpenId(String code, String source) {
@@ -117,8 +126,22 @@ public class UserAuthorizationServiceImpl implements UserAuthorizationService {
userInfo.setLastLoginTime(DateUtil.date().toLocalDateTime());
userInfoService.saveOrUpdate(userInfo);
initAc(userInfo);
// StpKit.USER.login(userInfo.getId());
StpKit.USER.login(userInfo.getId(), openId, null, null, null, MyStpLogic.LoginType.USER, false, "userMini", false);
return new LoginTokenDTO(StpKit.USER.getTokenValue(), userInfo);
String followIndex = paramsService.getSysParamValue(SysParamCodeEnum.FOLLOW_INDEX.getCode());
return new LoginTokenDTO(StpKit.USER.getTokenValue(), followIndex, userInfo);
}
/**
* 初始化用户微信公众号二维码\
*/
private void initAc(UserInfo userInfo) {
if (StrUtil.isBlank(userInfo.getWechatAcOpenId()) &&
(userInfo.getAcQrcodeValidTime() == null || userInfo.getAcQrcodeValidTime().isBefore(LocalDateTime.now()))) {
userInfo.setWechatAcQrcode(acAccountUtil.createQrCode(userInfo.getId()));
userInfo.setAcQrcodeValidTime(LocalDateTime.now().plusDays(29));
userInfoService.updateById(userInfo);
}
}
}

View File

@@ -0,0 +1,124 @@
package com.czg.service.account.util;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.czg.service.RedisService;
import com.czg.system.service.SysParamsService;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
/**
* 微信公众号
*
* @author ww
*/
@Data
@Slf4j
@Component
public class AcAccountUtil {
@Resource
@Lazy
private RedisService redisService;
@DubboReference
private SysParamsService paramsService;
static LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
static {
linkedHashMap.put("40001", "获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口");
linkedHashMap.put("40003", "不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID");
linkedHashMap.put("40014", "不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口");
linkedHashMap.put("40037", "不合法的 template_id");
linkedHashMap.put("43101", "用户未订阅消息");
linkedHashMap.put("43107", "订阅消息能力封禁");
linkedHashMap.put("43108", "并发下发消息给同一个粉丝");
linkedHashMap.put("45168", "命中敏感词");
linkedHashMap.put("47003", "参数错误");
}
/**
* 获取临时二维码用于关注公众号 30天即2592000秒后过期
*/
public String createQrCode(Long userId) {
String accessToken = Convert.toStr(redisService.get("accessToken"));
if (StrUtil.isNotEmpty(accessToken)) {
return accessToken;
}
JSONObject bodyJson = new JSONObject();
//二维码有效时间最大2592000仅临时二维码需要
bodyJson.put("expire_seconds", "2592000");
//二维码类型QR_SCENE(临时整型)/QR_STR_SCENE(临时字符串)/QR_LIMIT_SCENE(永久整型)/QR_LIMIT_STR_SCENE(永久字符串)
bodyJson.put("action_name", "QR_SCENE");
JSONObject actionInfo = new JSONObject();
JSONObject scene = new JSONObject();
scene.put("scene_id", userId);
actionInfo.put("scene", scene);
bodyJson.put("action_info", actionInfo);
String resp = HttpUtil.post(StrUtil.format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={}", getAccessToken()), bodyJson);
/**
* {
* "ticket": "gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGlu...",
* "expire_seconds": 60,
* "url": "http://weixin.qq.com/q/kZgfwMTm72WWPkovabbI"
* }
*/
JSONObject respInfo = JSONObject.parseObject(resp);
return respInfo.get("url").toString();
}
public String getAccessToken() {
String accessToken = Convert.toStr(redisService.get("wx:ac:AccessToken"));
if (StrUtil.isNotEmpty(accessToken)) {
return accessToken;
}
String acAppId = paramsService.getSysParamValue("wechat_ac_appid");
String acSecrete = paramsService.getSysParamValue("wechat_ac_secrete");
String resp = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", acAppId, acSecrete));
JSONObject respInfo = JSONObject.parseObject(resp);
if (!respInfo.containsKey("access_token")) {
log.warn("公众号获取token失败, 响应内容: {}", resp);
throw new RuntimeException(resp);
}
accessToken = respInfo.getString("access_token");
int expiresIn = respInfo.getInteger("expires_in");
redisService.set("wx:ac:AccessToken", accessToken, expiresIn - 10);
return accessToken;
}
public static void main(String[] args) {
String resp = HttpUtil.get(StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}",
"wx1fb600d0f5ea6279", "b4c0534c9b5e6c84a7fe5c2078dff876"));
JSONObject respInfo = JSONObject.parseObject(resp);
if (!respInfo.containsKey("access_token")) {
log.warn("公众号获取token失败, 响应内容: {}", resp);
throw new RuntimeException(resp);
}
String accessToken = respInfo.getString("access_token");
JSONObject bodyJson = new JSONObject();
//二维码有效时间最大2592000仅临时二维码需要
bodyJson.put("expire_seconds", "2592000");
//二维码类型QR_SCENE(临时整型)/QR_STR_SCENE(临时字符串)/QR_LIMIT_SCENE(永久整型)/QR_LIMIT_STR_SCENE(永久字符串)
bodyJson.put("action_name", "QR_SCENE");
JSONObject actionInfo = new JSONObject();
JSONObject scene = new JSONObject();
scene.put("scene_id", 3);
actionInfo.put("scene", scene);
bodyJson.put("action_info", actionInfo);
System.out.println(bodyJson);
String resps = HttpUtil.post(StrUtil.format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={}", accessToken), JSONObject.toJSONString(bodyJson));
JSONObject respInfos = JSONObject.parseObject(resps);
System.out.println(respInfos);
}
}