292 lines
12 KiB
Java
292 lines
12 KiB
Java
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());
|
||
}
|
||
}
|