¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.service; |
| | | |
| | | /** |
| | | * ä¼ä¸å¾®ä¿¡è天管çServiceæ¥å£ |
| | | * |
| | | * @author ageerle |
| | | * @date 2025-04-08 |
| | | */ |
| | | public interface IChatVxService { |
| | | |
| | | |
| | | /** |
| | | * ä¼ä¸å¾®ä¿¡åºç¨åå¤ |
| | | * @param prompt æç¤ºè¯ |
| | | * @return åå¤å
容 |
| | | */ |
| | | String chat(String prompt); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.service.impl; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletion; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse; |
| | | import org.ruoyi.common.chat.entity.chat.Message; |
| | | import org.ruoyi.common.chat.openai.OpenAiStreamClient; |
| | | import org.ruoyi.service.IChatVxService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | @Slf4j |
| | | @RequiredArgsConstructor |
| | | public class ChatVxServiceImpl implements IChatVxService { |
| | | |
| | | private final OpenAiStreamClient openAiStreamClient; |
| | | |
| | | @Override |
| | | public String chat(String prompt) { |
| | | List<Message> messageList = new ArrayList<>(); |
| | | Message message = Message.builder().role(Message.Role.USER).content(prompt).build(); |
| | | messageList.add(message); |
| | | ChatCompletion chatCompletion = ChatCompletion |
| | | .builder() |
| | | .messages(messageList) |
| | | .model("gpt-4o-mini") |
| | | .stream(false) |
| | | .build(); |
| | | ChatCompletionResponse chatCompletionResponse = openAiStreamClient.chatCompletion(chatCompletion); |
| | | return chatCompletionResponse.getChoices().get(0).getMessage().getContent().toString(); |
| | | } |
| | | |
| | | } |
| | |
| | | <module>ruoyi-chat</module> |
| | | <module>ruoyi-system</module> |
| | | <module>ruoyi-generator</module> |
| | | <module>ruoyi-wechat</module> |
| | | </modules> |
| | | |
| | | <properties> |
| | |
| | | UploadFileResponse upload(MultipartFile file); |
| | | |
| | | |
| | | /** |
| | | * ä¼ä¸åºç¨åå¤ |
| | | * @param prompt æç¤ºè¯ |
| | | * @return åå¤å
容 |
| | | */ |
| | | String wxCpChat(String prompt); |
| | | |
| | | } |
| | |
| | | import org.ruoyi.chat.util.SSEUtil; |
| | | import org.ruoyi.common.chat.config.LocalCache; |
| | | import org.ruoyi.common.chat.entity.Tts.TextToSpeech; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletion; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse; |
| | | import org.ruoyi.common.chat.entity.chat.Message; |
| | | import org.ruoyi.common.chat.entity.files.UploadFileResponse; |
| | | import org.ruoyi.common.chat.entity.whisper.WhisperResponse; |
| | |
| | | e.printStackTrace(); |
| | | } |
| | | return file; |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public String wxCpChat(String prompt) { |
| | | List<Message> messageList = new ArrayList<>(); |
| | | Message message = Message.builder().role(Message.Role.USER).content(prompt).build(); |
| | | messageList.add(message); |
| | | ChatCompletion chatCompletion = ChatCompletion |
| | | .builder() |
| | | .messages(messageList) |
| | | .model("gpt-4o-mini") |
| | | .stream(false) |
| | | .build(); |
| | | ChatCompletionResponse chatCompletionResponse = openAiStreamClient.chatCompletion(chatCompletion); |
| | | return chatCompletionResponse.getChoices().get(0).getMessage().getContent().toString(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <project xmlns="http://maven.apache.org/POM/4.0.0" |
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| | | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-modules</artifactId> |
| | | <version>${revision}</version> |
| | | <relativePath>../pom.xml</relativePath> |
| | | </parent> |
| | | |
| | | <artifactId>ruoyi-wechat</artifactId> |
| | | |
| | | <properties> |
| | | <maven.compiler.source>17</maven.compiler.source> |
| | | <maven.compiler.target>17</maven.compiler.target> |
| | | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.ruoyi</groupId> |
| | | <artifactId>ruoyi-chat-api</artifactId> |
| | | </dependency> |
| | | </dependencies> |
| | | |
| | | </project> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.builder; |
| | | |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | public abstract class AbstractBuilder { |
| | | public abstract WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage, WxCpService service); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.builder; |
| | | |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | public class ImageBuilder extends AbstractBuilder { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage, |
| | | WxCpService service) { |
| | | |
| | | WxCpXmlOutImageMessage m = WxCpXmlOutMessage.IMAGE().mediaId(content) |
| | | .fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) |
| | | .build(); |
| | | |
| | | return m; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.builder; |
| | | |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | public class TextBuilder extends AbstractBuilder { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage, |
| | | WxCpService service) { |
| | | WxCpXmlOutTextMessage m = WxCpXmlOutMessage.TEXT().content(content) |
| | | .fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) |
| | | .build(); |
| | | return m; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.config; |
| | | |
| | | |
| | | import com.google.common.collect.Maps; |
| | | import jakarta.annotation.PostConstruct; |
| | | import lombok.val; |
| | | import me.chanjar.weixin.common.api.WxConsts; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; |
| | | import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; |
| | | import me.chanjar.weixin.cp.constant.WxCpConsts; |
| | | import me.chanjar.weixin.cp.message.WxCpMessageHandler; |
| | | import me.chanjar.weixin.cp.message.WxCpMessageRouter; |
| | | import org.ruoyi.handler.*; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * åå®ä¾é
ç½® |
| | | * |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Configuration |
| | | @EnableConfigurationProperties(WxCpProperties.class) |
| | | public class WxCpConfiguration { |
| | | private final LogHandler logHandler; |
| | | private NullHandler nullHandler; |
| | | private LocationHandler locationHandler; |
| | | private MenuHandler menuHandler; |
| | | private MsgHandler msgHandler; |
| | | private final UnsubscribeHandler unsubscribeHandler; |
| | | private SubscribeHandler subscribeHandler; |
| | | private WxCpProperties properties; |
| | | |
| | | private static Map<Integer, WxCpMessageRouter> routers = Maps.newHashMap(); |
| | | private static Map<Integer, WxCpService> cpServices = Maps.newHashMap(); |
| | | |
| | | @Autowired |
| | | public WxCpConfiguration(LogHandler logHandler, NullHandler nullHandler, LocationHandler locationHandler, |
| | | MenuHandler menuHandler, MsgHandler msgHandler, UnsubscribeHandler unsubscribeHandler, |
| | | SubscribeHandler subscribeHandler, WxCpProperties properties) { |
| | | this.logHandler = logHandler; |
| | | this.nullHandler = nullHandler; |
| | | this.locationHandler = locationHandler; |
| | | this.menuHandler = menuHandler; |
| | | this.msgHandler = msgHandler; |
| | | this.unsubscribeHandler = unsubscribeHandler; |
| | | this.subscribeHandler = subscribeHandler; |
| | | this.properties = properties; |
| | | } |
| | | |
| | | |
| | | public static Map<Integer, WxCpMessageRouter> getRouters() { |
| | | return routers; |
| | | } |
| | | |
| | | public static WxCpService getCpService(Integer agentId) { |
| | | return cpServices.get(agentId); |
| | | } |
| | | |
| | | @PostConstruct |
| | | public void initServices() { |
| | | cpServices = this.properties.getAppConfigs().stream().map(a -> { |
| | | val configStorage = new WxCpDefaultConfigImpl(); |
| | | configStorage.setCorpId(this.properties.getCorpId()); |
| | | configStorage.setAgentId(a.getAgentId()); |
| | | configStorage.setCorpSecret(a.getSecret()); |
| | | configStorage.setToken(a.getToken()); |
| | | configStorage.setAesKey(a.getAesKey()); |
| | | val service = new WxCpServiceImpl(); |
| | | service.setWxCpConfigStorage(configStorage); |
| | | routers.put(a.getAgentId(), this.newRouter(service)); |
| | | return service; |
| | | }).collect(Collectors.toMap(service -> service.getWxCpConfigStorage().getAgentId(), a -> a)); |
| | | } |
| | | |
| | | private WxCpMessageRouter newRouter(WxCpService wxCpService) { |
| | | final val newRouter = new WxCpMessageRouter(wxCpService); |
| | | |
| | | // è®°å½ææäºä»¶çæ¥å¿ ï¼å¼æ¥æ§è¡ï¼ |
| | | newRouter.rule().handler(this.logHandler).next(); |
| | | |
| | | // èªå®ä¹èåäºä»¶ |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxConsts.MenuButtonType.CLICK).handler(this.menuHandler).end(); |
| | | |
| | | // ç¹å»èå龿¥äºä»¶ï¼è¿é使ç¨äºä¸ä¸ªç©ºçå¤çå¨ï¼å¯ä»¥æ ¹æ®èªå·±éè¦è¿è¡æ©å±ï¼ |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxConsts.MenuButtonType.VIEW).handler(this.nullHandler).end(); |
| | | |
| | | // å
³æ³¨äºä»¶ |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxConsts.EventType.SUBSCRIBE).handler(this.subscribeHandler) |
| | | .end(); |
| | | |
| | | // åæ¶å
³æ³¨äºä»¶ |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxConsts.EventType.UNSUBSCRIBE) |
| | | .handler((WxCpMessageHandler) this.unsubscribeHandler).end(); |
| | | |
| | | // 䏿¥å°çä½ç½®äºä»¶ |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxConsts.EventType.LOCATION).handler(this.locationHandler) |
| | | .end(); |
| | | |
| | | // æ¥æ¶å°çä½ç½®æ¶æ¯ |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION) |
| | | .handler(this.locationHandler).end(); |
| | | |
| | | // æ«ç äºä»¶ï¼è¿é使ç¨äºä¸ä¸ªç©ºçå¤çå¨ï¼å¯ä»¥æ ¹æ®èªå·±éè¦è¿è¡æ©å±ï¼ |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxConsts.EventType.SCAN).handler((WxCpMessageHandler) this.nullHandler).end(); |
| | | |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxCpConsts.EventType.CHANGE_CONTACT).handler(new ContactChangeHandler()).end(); |
| | | |
| | | newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) |
| | | .event(WxCpConsts.EventType.ENTER_AGENT).handler(new EnterAgentHandler()).end(); |
| | | |
| | | // é»è®¤ |
| | | newRouter.rule().async(false).handler(this.msgHandler).end(); |
| | | |
| | | return newRouter; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.config; |
| | | |
| | | import lombok.Data; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Data |
| | | public class WxCpProperties { |
| | | /** |
| | | * 设置ä¼ä¸å¾®ä¿¡çcorpId |
| | | */ |
| | | private String corpId; |
| | | |
| | | private List<AppConfig> appConfigs; |
| | | |
| | | @Getter |
| | | @Setter |
| | | public static class AppConfig { |
| | | /** |
| | | * 设置ä¼ä¸å¾®ä¿¡åºç¨çAgentId |
| | | */ |
| | | private Integer agentId; |
| | | |
| | | /** |
| | | * 设置ä¼ä¸å¾®ä¿¡åºç¨çSecret |
| | | */ |
| | | private String secret; |
| | | |
| | | /** |
| | | * 设置ä¼ä¸å¾®ä¿¡åºç¨çtoken |
| | | */ |
| | | private String token; |
| | | |
| | | /** |
| | | * 设置ä¼ä¸å¾®ä¿¡åºç¨çEncodingAESKey |
| | | */ |
| | | private String aesKey; |
| | | |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.controller.wxcplogin; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.ruoyi.common.core.utils.JsonUtils; |
| | | |
| | | import org.ruoyi.config.WxCpConfiguration; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/wx/cp") |
| | | @Slf4j |
| | | public class WxPortalController { |
| | | |
| | | @Value("${wechat.cp.appConfigs[0].agentId}") |
| | | private Integer agentId; |
| | | |
| | | |
| | | @GetMapping(produces = "text/plain;charset=utf-8") |
| | | public String authGet( |
| | | @RequestParam(name = "msg_signature", required = false) String signature, |
| | | @RequestParam(name = "timestamp", required = false) String timestamp, |
| | | @RequestParam(name = "nonce", required = false) String nonce, |
| | | @RequestParam(name = "echostr", required = false) String echostr) { |
| | | log.info("\næ¥æ¶å°æ¥èªå¾®ä¿¡æå¡å¨çè®¤è¯æ¶æ¯ï¼signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]", |
| | | signature, timestamp, nonce, echostr); |
| | | |
| | | if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) { |
| | | throw new IllegalArgumentException("请æ±åæ°éæ³ï¼è¯·æ ¸å®!"); |
| | | } |
| | | |
| | | final WxCpService wxCpService = WxCpConfiguration.getCpService(agentId); |
| | | if (wxCpService == null) { |
| | | throw new IllegalArgumentException(String.format("æªæ¾å°å¯¹åºagentId=[%d]çé
ç½®ï¼è¯·æ ¸å®ï¼", agentId)); |
| | | } |
| | | |
| | | if (wxCpService.checkSignature(signature, timestamp, nonce, echostr)) { |
| | | return new WxCpCryptUtil(wxCpService.getWxCpConfigStorage()).decrypt(echostr); |
| | | } |
| | | |
| | | return "éæ³è¯·æ±"; |
| | | } |
| | | |
| | | @PostMapping(produces = "application/xml; charset=UTF-8") |
| | | public String post( |
| | | @RequestBody String requestBody, |
| | | @RequestParam("msg_signature") String signature, |
| | | @RequestParam("timestamp") String timestamp, |
| | | @RequestParam("nonce") String nonce) { |
| | | log.info("\næ¥æ¶å¾®ä¿¡è¯·æ±ï¼[signature=[{}], timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", |
| | | signature, timestamp, nonce, requestBody); |
| | | |
| | | final WxCpService wxCpService = WxCpConfiguration.getCpService(1000002); |
| | | WxCpXmlMessage inMessage = WxCpXmlMessage.fromEncryptedXml(requestBody, wxCpService.getWxCpConfigStorage(), |
| | | timestamp, nonce, signature); |
| | | log.debug("\næ¶æ¯è§£å¯åå
容为ï¼\n{} ", JsonUtils.toJson(inMessage)); |
| | | WxCpXmlOutMessage outMessage = this.route(1000002, inMessage); |
| | | if (outMessage == null) { |
| | | return ""; |
| | | } |
| | | |
| | | String out = outMessage.toEncryptedXml(wxCpService.getWxCpConfigStorage()); |
| | | log.debug("\nç»è£
åå¤ä¿¡æ¯ï¼{}", out); |
| | | return out; |
| | | } |
| | | |
| | | private WxCpXmlOutMessage route(Integer agentId, WxCpXmlMessage message) { |
| | | try { |
| | | return WxCpConfiguration.getRouters().get(agentId).route(message); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import me.chanjar.weixin.cp.message.WxCpMessageHandler; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | public abstract class AbstractHandler implements WxCpMessageHandler { |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import org.ruoyi.builder.TextBuilder; |
| | | import org.ruoyi.common.core.utils.JsonUtils; |
| | | |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * é讯å½åæ´äºä»¶å¤çå¨. |
| | | * |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class ContactChangeHandler extends AbstractHandler { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) { |
| | | String content = "æ¶å°é讯å½åæ´äºä»¶ï¼å
容ï¼" + JsonUtils.toJson(wxMessage); |
| | | log.info(content); |
| | | |
| | | return new TextBuilder().build(content, wxMessage, cpService); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.chanjar.weixin.common.error.WxErrorException; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * <pre> |
| | | * |
| | | * Created by Binary Wang on 2018/8/27. |
| | | * </pre> |
| | | * |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Slf4j |
| | | public class EnterAgentHandler extends AbstractHandler { |
| | | private static final int TEST_AGENT = 1000002; |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, WxSessionManager sessionManager) throws WxErrorException { |
| | | // do something |
| | | return null; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.chanjar.weixin.common.api.WxConsts; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import org.ruoyi.builder.TextBuilder; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class LocationHandler extends AbstractHandler { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) { |
| | | if (wxMessage.getMsgType().equals(WxConsts.XmlMsgType.LOCATION)) { |
| | | //TODO æ¥æ¶å¤çç¨æ·åéçå°çä½ç½®æ¶æ¯ |
| | | try { |
| | | String content = "æè°¢åé¦ï¼æ¨ççå°çä½ç½®å·²æ¶å°ï¼"; |
| | | return new TextBuilder().build(content, wxMessage, null); |
| | | } catch (Exception e) { |
| | | log.error("ä½ç½®æ¶æ¯æ¥æ¶å¤ç失败", e); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | //䏿¥å°çä½ç½®äºä»¶ |
| | | log.info("\n䏿¥å°çä½ç½®ï¼çº¬åº¦ : {}\nç»åº¦ : {}\n精度 : {}", |
| | | wxMessage.getLatitude(), wxMessage.getLongitude(), String.valueOf(wxMessage.getPrecision())); |
| | | |
| | | //TODO å¯ä»¥å°ç¨æ·å°çä½ç½®ä¿¡æ¯ä¿åå°æ¬å°æ°æ®åºï¼ä»¥ä¾¿ä»¥åä½¿ç¨ |
| | | |
| | | return null; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import org.ruoyi.common.core.utils.JsonUtils; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class LogHandler extends AbstractHandler { |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) { |
| | | log.info("\næ¥æ¶å°è¯·æ±æ¶æ¯ï¼å
容ï¼{}", JsonUtils.toJson(wxMessage)); |
| | | return null; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import me.chanjar.weixin.common.api.WxConsts.MenuButtonType; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Component |
| | | public class MenuHandler extends AbstractHandler { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) { |
| | | |
| | | String msg = String.format("type:%s, event:%s, key:%s", |
| | | wxMessage.getMsgType(), wxMessage.getEvent(), |
| | | wxMessage.getEventKey()); |
| | | if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) { |
| | | return null; |
| | | } |
| | | |
| | | return WxCpXmlOutMessage.TEXT().content(msg) |
| | | .fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) |
| | | .build(); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import me.chanjar.weixin.common.api.WxConsts; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | |
| | | import org.ruoyi.builder.TextBuilder; |
| | | import org.ruoyi.service.IChatVxService; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Component |
| | | @RequiredArgsConstructor |
| | | public class MsgHandler extends AbstractHandler { |
| | | |
| | | private final IChatVxService chatVxService; |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) { |
| | | final String msgType = wxMessage.getMsgType(); |
| | | if (msgType == null) { |
| | | // 妿msgType没æï¼å°±èªå·±æ ¹æ®å
·ä½æ¥æå
容åå¤ç |
| | | } |
| | | |
| | | if (!msgType.equals(WxConsts.XmlMsgType.EVENT)) { |
| | | //TODO å¯ä»¥éæ©å°æ¶æ¯ä¿åå°æ¬å° |
| | | } |
| | | //TODO ç»è£
å夿¶æ¯ |
| | | String content = chatVxService.chat(wxMessage.getContent()); |
| | | |
| | | return new TextBuilder().build(content, wxMessage, cpService); |
| | | |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Component |
| | | public class NullHandler extends AbstractHandler { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) { |
| | | return null; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | public abstract class ScanHandler extends AbstractHandler { |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.chanjar.weixin.common.error.WxErrorException; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.WxCpUser; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import org.ruoyi.builder.TextBuilder; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class SubscribeHandler extends AbstractHandler { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) throws WxErrorException { |
| | | |
| | | log.info("æ°å
³æ³¨ç¨æ· OPENID: " + wxMessage.getFromUserName()); |
| | | |
| | | // è·åå¾®ä¿¡ç¨æ·åºæ¬ä¿¡æ¯ |
| | | WxCpUser userWxInfo = cpService.getUserService().getById(wxMessage.getFromUserName()); |
| | | |
| | | if (userWxInfo != null) { |
| | | // TODO å¯ä»¥æ·»å å
³æ³¨ç¨æ·å°æ¬å° |
| | | } |
| | | |
| | | WxCpXmlOutMessage responseResult = null; |
| | | try { |
| | | responseResult = handleSpecial(wxMessage); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | } |
| | | |
| | | if (responseResult != null) { |
| | | return responseResult; |
| | | } |
| | | |
| | | try { |
| | | return new TextBuilder().build("æè°¢å
³æ³¨", wxMessage, cpService); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * å¤çç¹æ®è¯·æ±ï¼æ¯å¦å¦ææ¯æ«ç è¿æ¥çï¼å¯ä»¥åç¸åºå¤ç |
| | | */ |
| | | private WxCpXmlOutMessage handleSpecial(WxCpXmlMessage wxMessage) { |
| | | //TODO |
| | | return null; |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.handler; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import me.chanjar.weixin.common.session.WxSessionManager; |
| | | import me.chanjar.weixin.cp.api.WxCpService; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; |
| | | import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @author <a href="https://github.com/binarywang">Binary Wang</a> |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | public class UnsubscribeHandler extends AbstractHandler { |
| | | |
| | | @Override |
| | | public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService cpService, |
| | | WxSessionManager sessionManager) { |
| | | String openId = wxMessage.getFromUserName(); |
| | | log.info("åæ¶å
³æ³¨ç¨æ· OPENID: " + openId); |
| | | // TODO å¯ä»¥æ´æ°æ¬å°æ°æ®åºä¸ºåæ¶å
³æ³¨ç¶æ |
| | | return null; |
| | | } |
| | | |
| | | } |