Files
gxtyzx-java/modules/common/system/controller/WxOfficialController.java
T
2024-08-13 17:51:18 +08:00

292 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.*;
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);
sendTemplateMessage(openId);
// 关注操作
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;
}
private void sendTemplateMessage(String openId){
String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + getAccessToken();
TemplateMessage templateMessage = new TemplateMessage();
templateMessage.setToUser(openId);
templateMessage.setTemplateId("dVSbX2NRzAG7IuN4kkCQhgV-LjzxvApN3PgrGlon9JU");
/*
您好,您已成功消费。
商品名:微信影城影票
消费时间:2013年8月20日 20:38
备注:您可以回复文字或语音对该商品及商家进行评价哦~
{{productType.DATA}}:{{name.DATA}} 消费时间:{{time.DATA}} {{remark.DATA}}
*/
HashMap<String, TemplateMessageDTO> data = new HashMap<>();
data.put("first",new TemplateMessageDTO("您收到了一条新的订单。"));
data.put("tradeDateTime",new TemplateMessageDTO("02月18日 01时05分"));
data.put("customerInfo",new TemplateMessageDTO("广州 王俊"));
data.put("orderItemName",new TemplateMessageDTO("兴趣车型"));
data.put("orderItemData",new TemplateMessageDTO("骐达 2011款 1.6 CVT 舒适版"));
data.put("remark",new TemplateMessageDTO("截止24日09:39分,您尚有10个订单未处理。"));
System.out.println("data = " + data);
// 链式构建请求
String result = HttpRequest.post(url)
.body(JSONObject.toJSONString(data))//表单内容
.timeout(20000)//超时,毫秒
.execute().body();
System.out.println("result = " + result);
System.out.println("getAccessToken() = " + getAccessToken());
}
@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(getAccessToken());
}
}