自动回复
This commit is contained in:
parent
bb55f4030f
commit
e8a7435a42
@ -5,16 +5,19 @@ import cn.skcks.docking.wx.common.json.JsonResponse;
|
|||||||
import cn.skcks.docking.wx.common.page.PageWrapper;
|
import cn.skcks.docking.wx.common.page.PageWrapper;
|
||||||
import cn.skcks.docking.wx.orm.entity.MpApp;
|
import cn.skcks.docking.wx.orm.entity.MpApp;
|
||||||
import cn.skcks.docking.wx.services.mp.service.MpAppService;
|
import cn.skcks.docking.wx.services.mp.service.MpAppService;
|
||||||
|
import cn.skcks.docking.wx.services.mp.vo.verify.SignatureVo;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.Parameters;
|
import io.swagger.v3.oas.annotations.Parameters;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springdoc.core.annotations.ParameterObject;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Tag(name = "微信公众号")
|
@Tag(name = "微信公众号")
|
||||||
@ -41,4 +44,10 @@ public class MpAppController {
|
|||||||
public JsonResponse<PageWrapper<MpApp>> getMpAppListPage(@RequestParam Integer pageNo, @RequestParam Integer pageSize) {
|
public JsonResponse<PageWrapper<MpApp>> getMpAppListPage(@RequestParam Integer pageNo, @RequestParam Integer pageSize) {
|
||||||
return JsonResponse.success(mpAppService.getMpAppPageList(pageNo,pageSize));
|
return JsonResponse.success(mpAppService.getMpAppPageList(pageNo,pageSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/{appId}")
|
||||||
|
public void verify(HttpServletRequest request, HttpServletResponse response,
|
||||||
|
@PathVariable String appId, @ParameterObject SignatureVo signatureVo) throws Exception {
|
||||||
|
mpAppService.service(request, response, appId, signatureVo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,31 @@
|
|||||||
package cn.skcks.docking.wx.services.mp.service;
|
package cn.skcks.docking.wx.services.mp.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.skcks.docking.wx.common.page.PageWrapper;
|
import cn.skcks.docking.wx.common.page.PageWrapper;
|
||||||
import cn.skcks.docking.wx.orm.entity.MpApp;
|
import cn.skcks.docking.wx.orm.entity.MpApp;
|
||||||
import cn.skcks.docking.wx.orm.mapper.MpAppMapper;
|
import cn.skcks.docking.wx.orm.mapper.MpAppMapper;
|
||||||
|
import cn.skcks.docking.wx.services.mp.vo.verify.SignatureVo;
|
||||||
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import io.micrometer.common.util.StringUtils;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
|
||||||
|
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
|
||||||
|
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -16,6 +33,96 @@ import java.util.List;
|
|||||||
public class MpAppService {
|
public class MpAppService {
|
||||||
private final MpAppMapper mpAppMapper;
|
private final MpAppMapper mpAppMapper;
|
||||||
|
|
||||||
|
private final Map<String, WxMpService> serviceMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
private void init(){
|
||||||
|
LambdaQueryChainWrapper<MpApp> queryWrapper = new LambdaQueryChainWrapper<>(mpAppMapper);
|
||||||
|
queryWrapper.ne(MpApp::getEnable, false);
|
||||||
|
List<MpApp> mpApps = queryWrapper.list();
|
||||||
|
|
||||||
|
new ForkJoinPool(Runtime.getRuntime().availableProcessors()).execute(() -> {
|
||||||
|
mpApps.parallelStream().forEach(mpApp -> {
|
||||||
|
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
|
||||||
|
config.setAppId(mpApp.getAppId());
|
||||||
|
config.setSecret(mpApp.getAppSecret());
|
||||||
|
config.setToken(mpApp.getToken());
|
||||||
|
config.setAesKey(mpApp.getEncodingAesKey());
|
||||||
|
|
||||||
|
WxMpService service = new WxMpServiceImpl();
|
||||||
|
service.setWxMpConfigStorage(config);
|
||||||
|
|
||||||
|
serviceMap.put(mpApp.getAppId(), service);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void service(HttpServletRequest request, HttpServletResponse response, String appId, SignatureVo signatureVo) throws IOException {
|
||||||
|
response.setContentType("text/html;charset=utf-8");
|
||||||
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
|
||||||
|
WxMpService wxMpService = serviceMap.get(appId);
|
||||||
|
if(ObjectUtils.anyNull(appId, signatureVo, wxMpService)){
|
||||||
|
response.getWriter().println("非法请求");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!wxMpService.checkSignature(signatureVo.getTimestamp(), signatureVo.getNonce(), signatureVo.getSignature())){
|
||||||
|
response.getWriter().println("非法请求");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 签名验证请求
|
||||||
|
String echostr = request.getParameter("echostr");
|
||||||
|
if(StringUtils.isNotBlank(echostr)){
|
||||||
|
response.getWriter().println(echostr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String encryptType = StringUtils.isBlank(request.getParameter("encrypt_type")) ?
|
||||||
|
"raw" :
|
||||||
|
request.getParameter("encrypt_type");
|
||||||
|
|
||||||
|
if ("raw".equals(encryptType)) {
|
||||||
|
// 明文传输的消息
|
||||||
|
WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(request.getInputStream());
|
||||||
|
// WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
|
||||||
|
// if(outMessage == null) {
|
||||||
|
// //为null,说明路由配置有问题,需要注意
|
||||||
|
// response.getWriter().write("");
|
||||||
|
// }
|
||||||
|
// response.getWriter().write(outMessage.toXml());
|
||||||
|
|
||||||
|
log.debug("\n[↓] 接收消息: \n{}", inMessage);
|
||||||
|
|
||||||
|
WxMpXmlOutMessage outMessage = WxMpXmlOutMessage.TEXT()
|
||||||
|
.toUser(inMessage.getFromUser())
|
||||||
|
.fromUser(inMessage.getToUser())
|
||||||
|
.content(DateUtil.now())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
log.debug("\n[↑] 响应消息: \n{}", outMessage);
|
||||||
|
response.getWriter().write(outMessage.toXml());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ("aes".equals(encryptType)) {
|
||||||
|
// // 是aes加密的消息
|
||||||
|
// String msgSignature = request.getParameter("msg_signature");
|
||||||
|
// WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(request.getInputStream(), wxMpConfigStorage, timestamp, nonce, msgSignature);
|
||||||
|
// WxMpXmlOutMessage outMessage = wxMpMessageRouter.route(inMessage);
|
||||||
|
// if(outMessage == null) {
|
||||||
|
// //为null,说明路由配置有问题,需要注意
|
||||||
|
// response.getWriter().write("");
|
||||||
|
// }
|
||||||
|
// response.getWriter().write(outMessage.toEncryptedXml(wxMpConfigStorage));
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
response.getWriter().println("不可识别的加密类型");
|
||||||
|
// return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有公众号列表
|
* 获取所有公众号列表
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package cn.skcks.docking.wx.services.mp.vo.verify;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(title="签名验证 Vo")
|
||||||
|
public class SignatureVo {
|
||||||
|
@Schema(description = "时间戳")
|
||||||
|
private String timestamp;
|
||||||
|
@Schema(description = "随机数")
|
||||||
|
private String nonce;
|
||||||
|
@Schema(description = "签名")
|
||||||
|
private String signature;
|
||||||
|
}
|
@ -4,3 +4,8 @@ spring:
|
|||||||
|
|
||||||
server:
|
server:
|
||||||
port: 18881
|
port: 18881
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
root: info
|
||||||
|
cn.skcks.docking.wx: debug
|
||||||
|
@ -10,3 +10,8 @@ spring:
|
|||||||
deserialization:
|
deserialization:
|
||||||
# 忽略没有的字段
|
# 忽略没有的字段
|
||||||
fail_on_unknown_properties: false
|
fail_on_unknown_properties: false
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
root: info
|
||||||
|
cn.skcks.docking.wx: debug
|
||||||
|
Loading…
Reference in New Issue
Block a user