关注公众号自动注册用户

This commit is contained in:
gxwebsoft
2023-11-09 16:44:33 +08:00
parent d0b9d8b494
commit f1e41ac4d1
13 changed files with 310 additions and 25 deletions

View File

@@ -56,6 +56,7 @@ public class MybatisPlusConfig {
"sys_tenant",
"sys_dictionary",
"sys_dictionary_data",
"sys_user_oauth",
"sys_email_record",
"sys_plug"
).contains(tableName);

View File

@@ -0,0 +1,12 @@
package com.gxwebsoft.common.core.constants;
public class PlatformConstants {
public static final String MP_OFFICIAL = "MP-OFFICIAL"; // 微信公众号
public static final String MP_WEIXIN = "MP-WEIXIN"; // 微信小程序
public static final String MP_ALIPAY = "MP-ALIPAY"; // 支付宝小程序
public static final String WEB = "WEB"; // web同H5
public static final String H5 = "H5"; // H5推荐使用 WEB
public static final String APP = "APP"; // App
public static final String MP_BAIDU = "MP-BAIDU"; // 百度小程序
public static final String MP_TOUTIAO = "MP-TOUTIAO"; // 百度小程序
}

View File

@@ -1,6 +0,0 @@
package com.gxwebsoft.common.core.constants;
public class WxOfficialConstants {
// 获取 Access token
public static final String GET_ACCESS_TOKEN_API = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
}

View File

@@ -53,7 +53,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
"/api/login-alipay/*",
"/api/wx-login/loginByMpWxPhone",
"/api/wxWorkQrConnect",
"/api/sys/user-plan-log/wx-pay/**"
"/api/sys/user-plan-log/wx-pay/**",
"/api/wx-official/**"
)
.permitAll()
.anyRequest()

View File

@@ -35,6 +35,8 @@ import java.io.File;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import static com.gxwebsoft.common.core.constants.PlatformConstants.MP_OFFICIAL;
import static com.gxwebsoft.common.core.constants.PlatformConstants.MP_WEIXIN;
import static com.gxwebsoft.common.core.constants.RedisConstants.ACCESS_TOKEN_KEY;
@RestController
@@ -136,6 +138,7 @@ public class WxLoginController extends BaseController {
addUser.setStatus(0);
addUser.setUsername(createUsername("wx_"));
addUser.setNickname("微信用户");
addUser.setPlatform(MP_WEIXIN);
addUser.setGradeId(2);
if(userParam.getPhone() != null){
addUser.setPhone(userParam.getPhone());

View File

@@ -0,0 +1,261 @@
package com.gxwebsoft.common.system.controller;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.file.IOUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.Role;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.entity.UserOauth;
import com.gxwebsoft.common.system.entity.UserRole;
import com.gxwebsoft.common.system.param.RoleParam;
import com.gxwebsoft.common.system.param.UserParam;
import com.gxwebsoft.common.system.service.RoleService;
import com.gxwebsoft.common.system.service.UserOauthService;
import com.gxwebsoft.common.system.service.UserRoleService;
import com.gxwebsoft.common.system.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.gxwebsoft.common.core.constants.PlatformConstants.MP_OFFICIAL;
@Api(tags = "微信公众号接口")
@RestController
@RequestMapping("/api/wx-official")
public class WxOfficialController extends BaseController {
// 公众号AppID
private static final String appid = "wxa67c676fc445590e";
// 秘钥
private static final String secret = "a450297b5ca8e081080148799d4e6b25";
// 订阅消息模板ID
private static final String templateId = "LBoByn-TLb2qJS7yR838lGRU-BA-RZE6jm-adb7AWPA";
// 小程序APPID
private static final String miniAppid = "wx541db955e7a62709";
@Resource
private UserService userService;
@Resource
private RoleService roleService;
@Resource
private UserRoleService userRoleService;
@Resource
private UserOauthService userOauthService;
@Resource
private RedisUtil redisUtil;
@ApiOperation("验证微信服务器")
@GetMapping("/{id}")
public String validate(@PathVariable("id") Integer tenantId,@RequestParam String nonce,@RequestParam String timestamp,@RequestParam String signature,@RequestParam String echostr){
System.out.println("nonce = " + nonce);
System.out.println("tenantId = " + tenantId);
if(tenantId == null){
return null;
}
String token = "gxwebsoft";
String[] array = new String[]{token, timestamp, nonce};
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(array);
// 将三个参数字符串拼接成一个字符串进行sha1加密
StringBuilder sb = new StringBuilder();
for (String str: array){
sb.append(str);
}
final String strSha1 = DigestUtil.sha1Hex(sb.toString());
if (strSha1.equals(signature)) {
return echostr;
}
return null;
}
@ApiOperation("接收微信的xml消息")
@Transactional(rollbackFor = {Exception.class})
@RequestMapping("/{id}")
@ResponseBody
public String receiveMessages(HttpServletRequest request,@PathVariable("id") Integer tenantId) throws IOException {
System.out.println("tenantId = " + tenantId);
Integer userId = 0; // 用户ID
// 从请求中获取XML数据
String xmlData = IOUtils.toString(request.getInputStream(), "UTF-8");
System.out.println("xmlData = " + xmlData);
// 解析XML数据
Document document = XmlUtil.parseXml(xmlData);
Element rootElement = XmlUtil.getRootElement(document);
Element FromUserName = XmlUtil.getElement(rootElement, "FromUserName");
String openId = FromUserName.getTextContent();
System.out.println("openId = " + openId);
if(StrUtil.isNotBlank(openId)){
// 获取用户基本信息(UnionID机制)
final String userStr = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + getAccessToken() + "&openid="+ openId +"&lang=zh_CN");
// 保存第三方用户信息表shop_user_oauth
final JSONObject jsonObject = JSONObject.parseObject(userStr);
final String unionid = jsonObject.getString("unionid");
final String subscribe = jsonObject.getString("subscribe");
System.out.println("unionid = " + unionid);
// 关注操作
if (subscribe != null &&subscribe.equals("1")) {
final int count = userOauthService.count(new LambdaQueryWrapper<UserOauth>().eq(UserOauth::getOauthType, MP_OFFICIAL).eq(UserOauth::getUnionid, unionid).eq(UserOauth::getTenantId,tenantId));
System.out.println("count = " + count);
if (count == 0) {
// 其他平台是否有注册过
final List<UserOauth> list = userOauthService.list(new LambdaQueryWrapper<UserOauth>().eq(UserOauth::getUnionid, unionid).eq(UserOauth::getDeleted, 0));
final int size = list.size();
// 新用户注册
if (size== 0) {
User user = new User();
user.setStatus(0);
user.setUsername("wxoff_".concat(RandomUtil.randomString(12)));
user.setStatus(0);
user.setNickname("微信公众号用户");
user.setPlatform(MP_OFFICIAL);
user.setGradeId(1);
user.setPassword(userService.encodePassword(CommonUtil.randomUUID16()));
user.setTenantId(tenantId);
user.setRecommend(0);
final RoleParam roleParam = new RoleParam();
roleParam.setTenantId(tenantId);
roleParam.setRoleCode("guest");
Role role = roleService.getByRoleCode(roleParam);
user.setRoleId(role.getRoleId());
if (userService.saveUser(user)) {
userId = user.getUserId();
// 添加用户角色
final UserRole userRole = new UserRole();
userRole.setUserId(user.getUserId());
userRole.setTenantId(user.getTenantId());
userRole.setRoleId(user.getRoleId());
userRoleService.save(userRole);
}
System.out.println("新微信公众号用户 = " + userId);
}
// 更新
if (!CollectionUtils.isEmpty(list)) {
for (UserOauth item: list){
if(item.getUserId() != null){
userId = item.getUserId();
}
}
System.out.println("其他平台有注册过 = " + userId);
}
// 保存第三方用户记录
final UserOauth userOauth = new UserOauth();
userOauth.setOauthType(MP_OFFICIAL);
userOauth.setUnionid(unionid);
userOauth.setOauthId(openId);
userOauth.setUserId(userId);
userOauth.setTenantId(tenantId);
boolean save = userOauthService.save(userOauth);
System.out.println("关注微信公众号 = " + save);
}
}
}
return null;
}
@ApiOperation("send发送订阅通知")
@PostMapping("/send")
public ApiResult<?> send(UserParam param) {
// send发送订阅通知
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend?access_token=" + getAccessToken();
final UserOauth userOauth = userOauthService.getOne(new LambdaQueryWrapper<UserOauth>().eq(UserOauth::getUserId, param.getUserId()).eq(UserOauth::getOauthType,"MP-OFFICIAL").eq(UserOauth::getDeleted, 0));
if(userOauth != null){
param.setOpenId(userOauth.getOauthId());
final String oauthId = userOauth.getOauthId();
// 跳转小程序链接
HashMap<String, String> miniprogram = new HashMap<>();
miniprogram.put("appid",miniAppid);
miniprogram.put("pagepath","pages/chat/chat?friendId=" + param.getUserId());
// 参数
HashMap<String, Object> data = new HashMap<>();
final HashMap<String, String> thing1 = new HashMap<>();
final HashMap<String, String> thing2 = new HashMap<>();
thing1.put("value","有新访客需要接待");
thing2.put("value","吉媒小红娘");
data.put("thing1",thing1);
data.put("thing2",thing2);
// 请求主服务器获取用户信息
HashMap<String, Object> map = new HashMap<>();
map.put("access_token", getAccessToken());
map.put("touser",oauthId); // "opEVj6e1YIlMyovkOQFCLJ7llmuI"
// 红娘来信通知
map.put("template_id", templateId);
map.put("miniprogram",JSONObject.toJSONString(miniprogram));
map.put("data",data);
// 新访客通知
// map.put("tid","XMpEsDHmZZqpiaAzmPqO0Gk_h39WCRkaNZ9VoSI9F34");
// map.put("page","https://admin.jimeigroup.cn");
// map.put("sceneDesc","消息提醒");
System.out.println("map = " + map);
// 链式构建请求
String result = HttpRequest.post(url)
.body(JSONObject.toJSONString(map))//表单内容
.timeout(20000)//超时,毫秒
.execute().body();
JSONObject jsonObject = JSONObject.parseObject(result);
System.out.println("jsonObject = " + jsonObject);
if(jsonObject != null){
return success(jsonObject);
}
}
return fail("请求失败",getAccessToken());
}
// 调用接口凭证
private String getAccessToken() {
String key = MP_OFFICIAL.concat(":access_token:5");
// 从缓存获取access_token
String value = redisUtil.get(key);
if (value != null) {
// 解析access_token
JSONObject response = JSON.parseObject(value);
return response.getString("access_token");
}
// 微信获取凭证接口https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
String apiUrl = "https://api.weixin.qq.com/cgi-bin/token";
// 组装url参数
String url = apiUrl.concat("?grant_type=client_credential").concat("&appid=").concat(appid).concat("&secret=").concat(secret);
// 执行get请求
String result = HttpUtil.get(url);
// 解析access_token
JSONObject response = JSON.parseObject(result);
if (response.getString("access_token") != null) {
// 存入缓存
redisUtil.set(key, result,7000L, TimeUnit.SECONDS);
return response.getString("access_token");
}
return null;
}
@ApiOperation("test")
@PostMapping("/test")
public ApiResult<?> count(){
final int count = userOauthService.count(new LambdaQueryWrapper<UserOauth>().eq(UserOauth::getOauthType, MP_OFFICIAL).eq(UserOauth::getUnionid, "o0FaIuKa2UsVp6FCbvmZlrcaBRCM"));
System.out.println("count = " + count);
return success(count);
}
}

View File

@@ -52,7 +52,6 @@ public class UserOauth implements Serializable {
private Integer status;
@ApiModelProperty(value = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@ApiModelProperty(value = "租户id")

View File

@@ -18,4 +18,5 @@ public interface RoleMapper extends BaseMapper<Role> {
@InterceptorIgnore(tenantLine = "true")
List<Role> selectListAll(@Param("param") RoleParam param);
}

View File

@@ -120,6 +120,18 @@ public class UserParam extends BaseParam {
@ApiModelProperty(value = "所在辖区")
private String region;
@ApiModelProperty("关注数")
private Integer followers;
@ApiModelProperty("粉丝数")
private Integer fans;
@ApiModelProperty("获赞数")
private Integer likes;
@ApiModelProperty("评论数")
private Integer commentNumbers;
@ApiModelProperty(value = "择偶区域")
@TableField(exist = false)
private String cityMate;
@@ -202,15 +214,7 @@ public class UserParam extends BaseParam {
@TableField(exist = false)
private Boolean showProfile;
@ApiModelProperty("关注数")
private Integer followers;
@ApiModelProperty("粉丝数")
private Integer fans;
@ApiModelProperty("获赞数")
private Integer likes;
@ApiModelProperty("评论数")
private Integer commentNumbers;
@ApiModelProperty("openId")
@TableField(exist = false)
private String openId;
}

View File

@@ -2,6 +2,7 @@ package com.gxwebsoft.common.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gxwebsoft.common.system.entity.Role;
import com.gxwebsoft.common.system.param.RoleParam;
/**
* 角色Service
@@ -10,5 +11,5 @@ import com.gxwebsoft.common.system.entity.Role;
* @since 2018-12-24 16:10:32
*/
public interface RoleService extends IService<Role> {
Role getByRoleCode(RoleParam roleParam);
}

View File

@@ -3,9 +3,12 @@ package com.gxwebsoft.common.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.system.entity.Role;
import com.gxwebsoft.common.system.mapper.RoleMapper;
import com.gxwebsoft.common.system.param.RoleParam;
import com.gxwebsoft.common.system.service.RoleService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 角色服务实现类
*
@@ -15,4 +18,9 @@ import org.springframework.stereotype.Service;
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
@Override
public Role getByRoleCode(RoleParam roleParam) {
final List<Role> roleList = baseMapper.selectListAll(roleParam);
return roleList.get(0);
}
}

View File

@@ -1,6 +1,6 @@
# 端口
server:
port: 9015
port: 9090
# socketIo
socketio:
port: 9191

View File

@@ -50,7 +50,7 @@ public class SysGenerator {
// "sys_industry"
// "sys_plug",
// "sys_company"
// "sys_user_oauth"
"sys_user_oauth"
// "sys_user_grade"
// "sys_user_referee"
// "sys_notice"
@@ -60,9 +60,9 @@ public class SysGenerator {
// "sys_chat_message",
// "sys_chat_conversation"
// "sys_user_group"
"sys_app",
"sys_app_user",
"sys_app_url"
// "sys_app",
// "sys_app_user",
// "sys_app_url"
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{