From 0afac42fb2e9d6e5291304dd0044ce3042b45d2b Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期六, 10 十月 2026 15:09:14 +0800
Subject: [PATCH] 短信模块提交

---
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.java                                    |   63 
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Wechat.class                                 |    0 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfig.class                                           |    0 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSendRequest.class                                        |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.java         |    2 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.java                             |   72 
 ruoyi-quartz/pom.xml                                                                                                 |    6 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.class                                |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.class                              |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.class                                 |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSendRequest.class                                              |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.class                                |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.java                                      |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.class                                 |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.java   |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.class           |    0 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/SmsController.java                                         |  126 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.java                                |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.class                                 |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/AbstractSmsSender.java                                             |   40 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.java                                  |  127 +
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.class                            |    0 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/BaseSmsaccountController.java                       |   30 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.class                    |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.java                                    |    2 
 smartor/src/main/java/com/smartor/service/impl/SubtaskSmsServiceImpl.java                                            |    5 
 pom.xml                                                                                                              |    8 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.java                             |    2 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.java            |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.class                     |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.java                           |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.class       |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.java                                   |  144 +
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.class                   |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.java                       |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.class    |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.class                            |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/MessageChannel.java                                                    |   37 
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties.class                                        |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.class                               |    0 
 ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst               |    2 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfigProvider.class                                   |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSendRequest.java                                          |   97 
 ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSenderFactory.class                                            |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.java                                   |   69 
 ruoyi-message/target/maven-archiver/pom.properties                                                                   |    5 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.java                                   |  149 +
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/Hello.java                                        |    2 
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiSms.class                               |    0 
 smartor/pom.xml                                                                                                      |    5 
 ruoyi-message/target/classes/com/ruoyi/message/SendException.class                                                   |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.class                             |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.java                                |   27 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.class                     |    0 
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Sms.class                                    |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.java                                |   56 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.java                       |   34 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.class                              |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$1.class                           |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.class              |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.class                                 |    0 
 ruoyi-message/pom.xml                                                                                                |  100 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.java                                  |   71 
 ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePropertiesBindingCheck.java                              |   95 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfig.java                                             |   86 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.class                                  |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/AbstractSmsSender.class                                           |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/SendResult.java                                                        |  159 +
 ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSendRequest.java                                                |   86 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.java                                   |   60 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/support/WxMpUtils.class                                        |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSender.java                                                     |   35 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.class                               |    0 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ShiyiSmsController.java                                   |    6 
 ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst                       |   77 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.class                             |    0 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceTelInfoController.java                             |    1 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.java                            |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.class                 |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.java                             |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsParamServiceImpl.java                                    |   29 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.java                      |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.class                     |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.java                              |    2 
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$MessagingInsert.class                        |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.java                                |    6 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.class                             |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.class                           |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.class                             |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.class                                |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.java                   |    2 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSenderFactory.java                                        |   78 
 smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java                                           |    2 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.java             |   54 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSenderFactory.class                                      |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.java                                  |  204 ++
 ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst                     |   85 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.java                              |   87 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.class                                    |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.java                |   76 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.class                                 |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.java                                    |  122 +
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsService.java                                   |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.class                            |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.java                              |    2 
 ruoyi-message/target/classes/com/ruoyi/message/config/MtSmsConfig.class                                              |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.class                              |    0 
 ruoyi-message/target/classes/wsdl/MessagingInsert.asmx                                                               |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/config/AliyunSmsConfig.java                                            |   28 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.java                            |    2 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.java                                   |   56 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.class                 |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/package-info.java                                 |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.class                         |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSender.class                                                   |    0 
 ruoyi-message/src/test/resources/message-binding-check.yml                                                           |   18 
 ruoyi-message/target/classes/com/ruoyi/message/config/AliyunSmsConfig.class                                          |    0 
 ruoyi-message/target/test-classes/com/ruoyi/message/config/MessagePropertiesBindingCheck.class                       |    0 
 ruoyi-message/target/classes/com/ruoyi/message/MessageChannel.class                                                  |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/config/RootMessageProperties.java                                      |  187 +
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.java                               |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.class                              |    0 
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageConfigValidator.class                                   |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.java                               |  114 +
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/support/WxMpUtils.java                                          |   30 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.class                                |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/config/MessageConfigValidator.java                                     |   94 
 ruoyi-message/src/main/resources/wsdl/MessagingInsert.asmx                                                           |    0 
 ruoyi-message/target/classes/message-binding-check.yml                                                               |   18 
 ruoyi-message/src/main/java/com/ruoyi/message/SendException.java                                                     |   46 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.java                               |    2 
 ruoyi-system/pom.xml                                                                                                 |    6 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.class |    0 
 ruoyi-message/target/ruoyi-message-3.8.5.jar                                                                         |    0 
 ruoyi-message/target/classes/com/ruoyi/message/config/RootMessageProperties.class                                    |    0 
 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java                                                         |  343 --
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiWechat.class                            |    0 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.class                              |    0 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.class                                  |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.java                                 |    2 
 ruoyi-message/target/classes/com/ruoyi/message/SendResult.class                                                      |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSender.java                                               |   32 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.class                                |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.java                               |  103 +
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.class                            |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.java                               |   79 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.java                         |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.class                             |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/package-info.class                               |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.java                                  |   82 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.class                          |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.class                                  |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.java                   |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.class                       |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.class                           |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.java                                    |    2 
 ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Xinhua.class                                 |    0 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.class                               |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.java                               |   68 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsRecordsServiceImpl.java                                  |   92 
 ruoyi-message/src/main/java/com/ruoyi/message/config/MessageProperties.java                                          |  222 ++
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.java                                     |    2 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/Hello.class                                      |    0 
 smartor/src/main/java/com/smartor/service/impl/XHGatherPatArchiveServiceImpl.java                                    |   47 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.java                              |   65 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsService.class                                 |    0 
 ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java                                               |  393 --
 ruoyi-message/target/test-classes/com/ruoyi/message/config/PerSiteBindingCheck.class                                 |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSenderFactory.java                                              |  108 +
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$SendSmsRequestAdapter.class       |    0 
 ruoyi-message/target/test-classes/message-binding-check.yml                                                          |   18 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.class                          |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.java                                  |   74 
 ruoyi-message/src/main/java/com/ruoyi/message/config/XhsmsConfig.java                                                |   33 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.class                           |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.java                                 |   86 
 smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java                                        |  105 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.java                     |    2 
 ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePrefixBindingCheck.java                                  |  165 +
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.class                             |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.class          |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.class                                  |    0 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.class                             |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.java                               |   46 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.java                       |    2 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.java                                 |  113 +
 ruoyi-admin/pom.xml                                                                                                  |    5 
 ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.class                                   |    0 
 ruoyi-message/src/main/java/com/ruoyi/message/config/MtSmsConfig.java                                                |   48 
 ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSender.class                                             |    0 
 ruoyi-message/src/test/java/com/ruoyi/message/config/PerSiteBindingCheck.java                                        |  106 +
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.java                                |  197 +
 /dev/null                                                                                                            |   87 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSLTDHealthcareRecordController.java                |    5 
 ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfigProvider.java                                     |   19 
 ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.java      |    2 
 ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst             |    2 
 ruoyi-message/target/classes/com/ruoyi/message/config/XhsmsConfig.class                                              |    0 
 198 files changed, 4,983 insertions(+), 1,036 deletions(-)

diff --git a/pom.xml b/pom.xml
index 69365d2..875721c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -185,6 +185,13 @@
                 <version>${ruoyi.version}</version>
             </dependency>
 
+            <!-- 娑堟伅鍙戦�侊紙鐭俊/寰俊鍏紬鍙凤級妯″潡 -->
+            <dependency>
+                <groupId>com.ruoyi</groupId>
+                <artifactId>ruoyi-message</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 
@@ -195,6 +202,7 @@
         <module>ruoyi-quartz</module>
         <module>ruoyi-generator</module>
         <module>ruoyi-common</module>
+        <module>ruoyi-message</module>
         <module>smartor</module>
     </modules>
     <packaging>pom</packaging>
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 674fcad..735cba5 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -87,6 +87,11 @@
             <version>3.8.5</version>
             <scope>compile</scope>
         </dependency>
+        <!-- 娑堟伅鍙戦�侊紙鐭俊/寰俊鍏紬鍙凤級妯″潡 -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-message</artifactId>
+        </dependency>
         <!-- https://mvnrepository.com/artifact/net.glxn.qrgen/javase -->
         <dependency>
             <groupId>net.glxn.qrgen</groupId>
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java b/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
index 06955a7..bc3425e 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/component/RedisMqReceiver.java
@@ -5,23 +5,18 @@
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 import com.ruoyi.common.core.redis.RedisCache;
-import com.ruoyi.common.dx.MessageSend;
-import com.ruoyi.common.enums.MsgLSEnum;
 import com.ruoyi.common.enums.ServiceFromEnum;
-import com.ruoyi.common.enums.WxGZHEnum;
-import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.*;
-import com.ruoyi.common.utils.http.HttpUtils;
-import com.ruoyi.common.utils.sign.Md5Utils;
-import com.ruoyi.common.utils.sms.smsUtils;
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSenderFactory;
 import com.ruoyi.system.domain.SysConfig;
 import com.ruoyi.system.mapper.SysConfigMapper;
 import com.ruoyi.system.service.ISysConfigService;
-import com.smartor.common.LSHospTokenUtil;
-import com.smartor.common.MtSubmitSmUtil;
 import com.smartor.domain.*;
 import com.smartor.domain.entity.ServiceSubtaskEntity;
 import com.smartor.mapper.*;
@@ -38,17 +33,11 @@
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 import org.springframework.stereotype.Component;
 
-import java.io.IOException;
 import java.net.URLEncoder;
-import java.security.MessageDigest;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
-
-import static cn.hutool.core.convert.Convert.toHex;
 
 @Slf4j
 @Component//鐩戝惉姝ら槦鍒�
@@ -100,26 +89,23 @@
     @Autowired
     IBaseSmsaccountService baseSmsaccountService;
 
-    @Value("${xhsmsPath}")
-    private String xhsmsPath;
-
-    @Value("${xhsmsAccount}")
-    private String xhsmsAccount;
-
-    @Value("${xhsmsPwd}")
-    private String xhsmsPwd;
-    // 铏氭嫙鎺ュ叆鐮�
-    @Value("${xhsmsjrm}")
-    private String xhsmsjrm;
-
     @Value("${server.port}")
     private String port;
 
-    @Value("${spring.profiles.active}")
-    private String active;
+    /**
+     * 娑堟伅鍙戦�佹柟宸ュ巶锛堢煭淇�/寰俊鍏紬鍙凤級銆�
+     * <p>
+     * 鍘熸潵鐭俊涓庡叕浼楀彿鐨勫彂閫侀�昏緫鍦ㄦ湰绫婚噷鐢� {@code if (active.equals("xx"))} 纭垎鏀簡绾� 300 琛岋紝
+     * 鐜板凡鏀跺彛鍒� {@code ruoyi-message} 妯″潡锛岃繖閲屽彧璐熻矗鎸� {@code active} 璺敱銆�
+     */
+    @Autowired
+    private SmsSenderFactory smsSenderFactory;
 
     @Autowired
-    private MtSubmitSmUtil mtSubmitSmUtil;
+    private WechatSenderFactory wechatSenderFactory;
+
+    @Value("${spring.profiles.active}")
+    private String active;
 
     @Autowired
     private ISysConfigService configService;
@@ -426,120 +412,11 @@
                         iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                     }
 
-                    //鐭俊杩橀渶瑕佹ā鏉�
-                    String s = null;
-                    if (active.equals("xh")) {
-                        //鏂板崕鐨勭煭淇″彂閫佹柟寮�
-                        Map<String, String> map2 = new HashMap<String, String>();
-                        map2.put("action", "send");
-                        map2.put("account", xhsmsAccount);
-                        map2.put("password", xhsmsPwd);
-                        map2.put("mobile", sendMagParam.getPhone());
-                        map2.put("content", sendMagParam.getContent());
-                        map2.put("extno", xhsmsjrm);
-                        map2.put("rt", "json");
-                        StringBuilder encodedParams = new StringBuilder();
-
-                        for (Map.Entry<String, String> entry : map2.entrySet()) {
-                            if (encodedParams.length() > 0) {
-                                encodedParams.append("&");
-                            }
-                            // 瀵归敭鍜屽�艰繘琛孶RL缂栫爜
-                            String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
-                            String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
-                            encodedParams.append(encodedKey).append("=").append(encodedValue);
-                        }
-                        Boolean isSuccess = HttpUtil.postJsonRequest(xhsmsPath, encodedParams.toString());
-                        if (isSuccess) s = "true";
-                    } else if (active.equals("ls")) {
-                        //涓芥按鐨勭煭淇″彂閫佹柟寮�
-                        SysConfig config = new SysConfig();
-                        config.setConfigKey("ls.msg.info");
-                        config.setOrgid(serviceSubtask.getOrgid());
-                        List<SysConfig> sysConfigs = configService.selectConfigList(config);
-                        Map<String, String> msgInfo = new HashMap<>();
-                        if (CollectionUtils.isNotEmpty(sysConfigs)) {
-                            String configValue = sysConfigs.get(0).getConfigValue();
-                            ObjectMapper objectMapper = new ObjectMapper();
-                            if (StringUtils.isNotEmpty(configValue)) {
-                                msgInfo = objectMapper.readValue(configValue, Map.class);
-                            }
-                        }
-                        log.info("-----------map鐨勫�间负锛歿}", msgInfo);
-
-                        if (ObjectUtils.isNotEmpty(msgInfo) && StringUtils.isEmpty(msgInfo.get("address"))) {
-                            serviceSubtask.setCurrentPreachform(sendPreachform);
-                            serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
-                            setFailPreachForm(serviceSubtask, descByCode, "鐭俊鍙戦�佸け璐�,璇ユ満鏋勬病鏈夐厤缃煭淇″湴鍧�", "5");
-                            serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
-                            continue;
-                        }
-
-                        String token = LSHospTokenUtil.getToken(serviceSubtask.getOrgid(), msgInfo.get("tokenUrl"));
-                        String dxCode = getDXCode(msgInfo.get("address"), sendMagParam.getPhone(), sendMagParam.getContent(), msgInfo.get("sendPersonId"), msgInfo.get("sendPersonName"), MsgLSEnum.getHeaderByCode(msgInfo), token);
-                        ObjectMapper objectMapper = new ObjectMapper();
-                        Map<String, Object> textParam = objectMapper.readValue(dxCode, Map.class);
-                        String code = textParam.get("Code").toString();
-                        if (code.equals("0")) {
-                            s = "true";
-                        } else {
-                            setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
-                            throw new BaseException("鐭俊鍙戦�佸け璐�");
-                        }
-                    } else if (active.equals("sltd") || active.equals("nhfy")) {
-                        //鐪佺珛鍚屽痉鐨勭煭淇″彂閫佹柟寮�
-                        String data = null;
-                        Map<String, Object> smsResult = null;
-                        if (active.equals("sltd")) {
-                            data = MessageSend.sendMsg(sendMagParam.getContent(), "6", sendMagParam.getPhone(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
-                            if (StringUtils.isNotEmpty(data)) {
-                                String[] pairs = data.split("&");
-                                String resultVal = null;
-                                for (String pair : pairs) {
-                                    String[] kv = pair.split("=", 2);
-                                    if ("result".equals(kv[0])) {
-                                        resultVal = kv.length > 1 ? kv[1] : null;
-                                        break;
-                                    }
-                                }
-                                if ("0".equals(resultVal)) {
-                                    s = "true";
-                                }
-                            } else {
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�: " + data, "5");
-                                throw new BaseException("鐭俊鍙戦�佸け璐�");
-                            }
-                        } else if (active.equals("nhfy")) {
-                            smsResult = mtSubmitSmUtil.submitSm(sendMagParam.getPhone(), sendMagParam.getContent());
-                            if (smsResult != null && smsResult.get("result") != null && smsResult.get("result").toString().equals("0")) {
-                                s = "true";
-                            } else {
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
-                                throw new BaseException("鐭俊鍙戦�佸け璐�");
-                            }
-                        }
-
-                    } else if (active.equals("hzszlyy")) {
-                        //甯備竴
-                        long timestamp = new Date().getTime();
-                        String sign = Md5Utils.hash(xhsmsAccount + timestamp + Md5Utils.hash(xhsmsPwd));
-                        String content = sendMagParam.getContent();
-                        String jsonMsg = "{" + "\"userName\": \"" + xhsmsAccount + "\"," + "\"content\": \"" + content + "\"," + "\"phoneList\": [" + sendMagParam.getPhone() + "]," + "\"timestamp\": " + timestamp + "," + "\"sign\": \"" + sign + "\"" + "}";
-                        Boolean b = HttpUtil.postJsonRequest(xhsmsPath, jsonMsg);
-                        if (b) s = "true";
-                        log.info("------甯備竴鐭俊鍙戦�佺殑鍊间负锛歿}", s);
-                        if (StringUtils.isNotEmpty(s)) {
-                            JSONObject jsonObject = JSONObject.parseObject(s);
-                            Object code = jsonObject.get("code");
-                            if (code.equals(0)) {
-                                s = "true";
-                            } else {
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
-                                throw new BaseException("鐭俊鍙戦�佸け璐�");
-                            }
-                        }
-                    }
-                    if (s.equals("true")) {
+                    //鐭俊鍙戦�侊細鍚勭珯鐐瑰鎺ユ柟寮忓樊寮傝緝澶э紙鎶ユ枃/绛惧悕/token/杩斿洖鍒ゅ畾閮戒笉鍚岋級锛�
+                    //宸叉敹鍙e埌 ruoyi-message 妯″潡锛岃繖閲屽彧璐熻矗缁勮鍏ュ弬骞惰矾鐢�
+                    log.info("----active鐨勫�间负锛歿}", active);
+                    SendResult smsSendResult = sendSmsByActive(serviceSubtask, sendMagParam);
+                    if (smsSendResult.isOk()) {
                         //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
                         setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佹垚鍔�", "2");
                         //浠诲姟鍙戦�佽褰�
@@ -553,10 +430,10 @@
                         serviceSubtaskRecord.setResult("success");
                         serviceSubtaskRecord.setRemark("鐭俊鍙戦�佹垚鍔�");
                         serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
-                        log.error("serviceSubtaskRecord淇濆瓨鎴愬姛浜嗗悧锛燂細{}", serviceSubtaskRecord);
                     } else {
                         //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
                         setFailPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�", "5");
+                        continue;
                     }
                 } catch (Exception e) {
                     ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
@@ -668,58 +545,28 @@
                         serviceOutPath.setUrl(url);
                         iServiceOutPathService.updateServiceOutPath(serviceOutPath);
                     }
-                    if (StringUtils.isEmpty(patArchive.getPatidHis())) {
-                        serviceSubtask.setCurrentPreachform(sendPreachform);
-                        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
-                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
-                        //澶辫触璁板綍
-                        setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佸け璐�,his绯荤粺鐨勬偅鑰卛d涓虹┖", "5");
-                        continue;
-                    }
-
-                    //鑾峰彇寰俊鍏紬鍙疯姹備俊鎭牴鎹満鏋処D
+                    //鏈烘瀯閰嶇疆鏍¢獙锛圵xGZHEnum锛変笌 his 鎮h�卛d 鏍¢獙宸叉敹鍙e埌
+                    //ruoyi-message 鐨� WechatMpConfigProvider / XinHuaMpSender锛岃皟鐢ㄧ偣涓嶅啀閲嶅鏍¢獙
                     log.error("鑾峰彇寰俊鍏紬鍙疯姹備俊鎭牴鎹満鏋処D锛歿}", patArchive.getOrgid());
-                    List<String> wxqqxx = WxGZHEnum.getDescByCode(patArchive.getOrgid());
-                    //甯備竴鍖婚櫌 涓嶆牎楠�
-                    if (CollectionUtils.isEmpty(wxqqxx) || wxqqxx.size() < 4) {
-                        serviceSubtask.setCurrentPreachform(sendPreachform);
-                        serviceSubtask.setVisitTime(getNextVisitTime(serviceSubtask.getId(), serviceSubtask.getTaskid(), serviceSubtask.getVisitTime(), serviceSubtask.getCurrentPreachform()));
-                        serviceSubtaskMapper.updateServiceSubtask(serviceSubtask);
-
-                        //澶辫触璁板綍
-                        setFailPreachForm(serviceSubtask, sendPreachform, "璇ユ満鏋勭殑鍏紬鍙烽厤缃俊鎭笉鍏紝鏃犳硶閫氳繃鍏紬鍙峰彂閫�", "5");
-                        continue;
-                    }
-                    String wxCode = "";
-                    if (active.equals("hzszlyy")) {
-                        wxCode = smsUtils.sendChat(url, patArchive.getTelcode(), serviceSubtask.getSfzh());
-                        log.info("wxCode鐨勫�间负:{}", wxCode);
+                    if (!"xh".equals(active)) {
+                        //甯備竴锛氳蛋鑷湁鍏紬鍙风綉鍏筹紙涓嶅仛鏈烘瀯閰嶇疆鏍¢獙銆乭is鎮h�卛d鏍¢獙锛屼笌鍘熷疄鐜颁竴鑷达級
+                        sendWechatByActive(serviceSubtask, patArchive, url);
                     } else {
-                        wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskName(), patArchive.getTelcode(), patArchive.getName(), patArchive.getPatidHis(), wxqqxx);
-                        log.error("wxCode鐨勫�间负:{}", wxCode);
-                        Map<String, Object> map = JSONObject.parseObject(wxCode, Map.class);
-                        log.error("map鐨勫�间负:{}", map);
-                        if (!map.isEmpty()) {
-                            serviceSubtask.setResult("success");
-                            serviceSubtask.setSendstate(3L);
-                            log.error("aBoolean鐨勫�间负:{}", aBoolean);
-                            if (map.get("succ").toString().equals("true")) {
-                                aBoolean = true;
-                            }
-                            if (aBoolean == false) {
-                                ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
-                                serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
-                                serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
-                                serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
-                                serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
-                                serviceSubtaskRecord.setPreachform("5");
-                                serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
-                                serviceSubtaskRecord.setRemark(ObjectUtils.isNotEmpty(map.get("msg")) ? map.get("msg").toString() : null);
-                                serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
-                                //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
-                                setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佸け璐�", "5");
-                                continue;
-                            }
+                        //鏂板崕锛歨is鎮h�卛d鏍¢獙澶辫触鍗宠褰曞苟杩涘叆涓嬩竴绉嶅彂閫佹柟寮�
+                        SendResult wechatSendResult = sendWechatByActive(serviceSubtask, patArchive, url);
+                        if (!wechatSendResult.isOk()) {
+                            ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
+                            serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
+                            serviceSubtaskRecord.setSubtaskId(serviceSubtask.getId());
+                            serviceSubtaskRecord.setUuid(UUID.randomUUID().toString());
+                            serviceSubtaskRecord.setTasktype(serviceSubtask.getType());
+                            serviceSubtaskRecord.setPreachform("5");
+                            serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
+                            serviceSubtaskRecord.setRemark(wechatSendResult.getMessage());
+                            serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
+                            //鍦ㄥ瓙浠诲姟琛ㄩ噷璁板綍涓�涓�
+                            setFailPreachForm(serviceSubtask, sendPreachform, "鍏紬鍙峰彂閫佸け璐�", "5");
+                            continue;
                         }
                     }
                 } catch (Exception e) {
@@ -758,6 +605,52 @@
             }
         }
 
+    }
+
+    /**
+     * 鎸� {@code active}锛堢珯鐐癸級璺敱鍒板搴旂殑鐭俊鍙戦�佹柟銆�
+     * <p>
+     * 鍏ュ弬娌跨敤鍘熷垎鏀噷宸茬粡缁勮濂界殑 {@code SendMagParam}锛屼繚璇佸唴瀹逛笌绾夸笂瀹屽叏涓�鑷淬��
+     * 鍚勭珯鐐瑰樊寮傝 {@code ruoyi-message} 妯″潡鍚勫疄鐜扮被銆�
+     * <p>
+     * 鈿狅笍 鏂板崕锛坽@code xh}锛夊湪鏈叆鍙e師鏈蛋銆孶RL 缂栫爜琛ㄥ崟銆嶏紝
+     * 涓� {@code RyTask}锛堝彂绌烘姤鏂囷級/ {@code smsSubTask}锛圝SON锛夊苟涓嶄竴鑷达紱
+     * 杩欓噷鎸夊師鏍疯蛋 {@code XinHuaSmsSender#sendForm}锛堣〃鍗曟ā寮忥級銆�
+     */
+    private SendResult sendSmsByActive(ServiceSubtask serviceSubtask, SendMagParam sendMagParam) {
+        SmsSendRequest request = SmsSendRequest.of(
+                sendMagParam.getPhone(), sendMagParam.getContent(), serviceSubtask.getOrgid());
+        return smsSenderFactory.send(active, request);
+    }
+
+    /**
+     * 鎸� {@code active}锛堢珯鐐癸級璺敱鍒板搴旂殑寰俊鍏紬鍙峰彂閫佹柟銆�
+     * <p>
+     * 鈿狅笍 绔欑偣宸紓锛堜笌鍘熷疄鐜颁竴涓�瀵瑰簲锛夛細
+     * <ul>
+     *   <li>甯備竴锛坽@code hzszlyy}锛夛細涓嶅仛 his 鎮h�卛d 鏍¢獙锛屾爣棰�/鍐呭閮藉彇浠诲姟鍚嶇О锛�</li>
+     *   <li>鏂板崕锛坽@code xh}锛夛細瑕佹眰 his 鎮h�卛d 闈炵┖锛屾偅鑰呭鍚嶅彇 {@code patArchive.getName()}锛�</li>
+     *   <li>鏂板崕鐨� JSON 鎶ユ枃浣撻渶瑕� {@code disableHtmlEscaping}锛屼笌 {@code RyTask} 涓嶅悓銆�</li>
+     * </ul>
+     */
+    private SendResult sendWechatByActive(ServiceSubtask serviceSubtask, PatArchive patArchive, String url) {
+        if (StringUtils.isEmpty(patArchive.getPatidHis())) {
+            return SendResult.fail(active, MessageChannel.WECHAT,
+                    "鍏紬鍙峰彂閫佸け璐�,his绯荤粺鐨勬偅鑰卛d涓虹┖", null);
+        }
+        WechatSendRequest request = new WechatSendRequest();
+        request.setOrgid(patArchive.getOrgid());
+        request.setIdCard(serviceSubtask.getSfzh());
+        request.setUrl(url);
+        request.setTitle(serviceSubtask.getTaskName());
+        //鍘熷疄鐜版爣棰樹笌鍐呭閮戒紶 serviceSubtask.getTaskName()
+        request.setContent(serviceSubtask.getTaskName());
+        request.setPhone(patArchive.getTelcode());
+        request.setPatientName(patArchive.getName());
+        request.setPatidHis(patArchive.getPatidHis());
+        //鍘� RedisMqReceiver.getWXCode 浣跨敤 disableHtmlEscaping锛屼笌 RyTask 涓嶅悓锛屾澶勪繚鎸�
+        request.setDisableHtmlEscaping(true);
+        return wechatSenderFactory.send(active, request);
     }
 
     private String getSC(ServiceSubtask serviceSubtask, String scriptContent) {
@@ -995,106 +888,12 @@
         return targetKey;
     }
 
-//    private String getKey() {
-//        Map<String, List> map = new HashMap<>();
-//        for (int i = 0; i < 6; i++) {
-//            Boolean aBoolean = redisCache.hasKey("cache-" + i);
-//            if (!aBoolean) {
-//                redisCache.setCacheList("cache-" + i, new ArrayList<String>());
-//                map.put("cache-" + i, new ArrayList<String>());
-//            } else {
-//                map.put("cache-" + i, redisCache.getCacheObject("cache-" + i));
-//            }
-//        }
-//
-//        String key = null;
-//        List<String> value = new ArrayList<String>();
-//        for (Map.Entry<String, List> entry : map.entrySet()) {
-//            if (CollectionUtils.isEmpty(value)) {
-//                value = entry.getValue();
-//                key = entry.getKey();
-//            } else {
-//                value = entry.getValue();
-//                key = entry.getKey();
-//            }
-//        }
-//        return key;
-//    }
-
-    private String getWXCode(String idcard, String url, String taskName, String taskDesc, String phone, String patientname, String setPatientid, List<String> wxqqxx) {
-        XinHuaWXReq xinHuaWXReq = new XinHuaWXReq();
-        xinHuaWXReq.setIdcard(idcard);
-        xinHuaWXReq.setUrl(url);
-        xinHuaWXReq.setPatientid(setPatientid);
-        xinHuaWXReq.setPatientname(patientname);
-        xinHuaWXReq.setMobile(phone);
-        xinHuaWXReq.setMedcardno(null);
-        xinHuaWXReq.setTitlename(taskName);
-        xinHuaWXReq.setContent(taskDesc);
-        xinHuaWXReq.setAppid(wxqqxx.get(1));
-        log.error("-----寰俊鍏紬鍙风殑鍑哄弬涓�----锛歿}", xinHuaWXReq);
-//         new Gson().toJson(xinHuaWXReq);
-        GsonBuilder gb = new GsonBuilder();
-        gb.disableHtmlEscaping();
-        String body = gb.create().toJson(xinHuaWXReq);
-
-        log.error("encode鐨勫叆鍙備负wxqqxx 锛歿},   body:{}", wxqqxx.get(2), body);
-        String encode = encode(wxqqxx.get(2).concat(body));
-        log.error("--------encode鐨勫�间负锛歿}-----", encode);
-        Map<String, String> headerMap = new HashMap<>();
-        headerMap.put("sign", encode);
-        String result = HttpUtils.sendPostByHeader(wxqqxx.get(3), body, headerMap);
-        log.error("--------result鐨勫�间负锛歿}-----", result);
-
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
-
-
-    private String getDXCode(String address, String ShouJiHM, String FaSongNR, String FaSongRID, String FaSongRXM, Map<String, Object> headerMap, String token) {
-        Map<String, Object> map = new LinkedHashMap<>();
-
-        Map<String, Object> YeWuXX = new LinkedHashMap<>();
-        Map<String, Object> DuanXinXX = new LinkedHashMap<>();
-        DuanXinXX.put("ShouJiHM", ShouJiHM);
-        DuanXinXX.put("FaSongNR", FaSongNR);
-        DuanXinXX.put("FaSongRID", FaSongRID);
-        DuanXinXX.put("FaSongRXM", FaSongRXM);
-        YeWuXX.put("DuanXinXX", DuanXinXX);
-
-        map.put("XiaoXiTou", headerMap);
-        map.put("YeWuXX", YeWuXX);
-
-        String body = new Gson().toJson(map);
-
-        String result = null;
-        try {
-            result = OkHttpExample.sendPostRequest(address, body, token);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        log.info("--------result鐨勫�间负锛歿}-----", result);
-
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
-
-
-    public String encode(String arg) {
-        if (arg == null) {
-            arg = "";
-        }
-        MessageDigest md5 = null;
-        try {
-            md5 = MessageDigest.getInstance("MD5");
-            md5.update(arg.getBytes("UTF-8"));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return toHex(md5.digest());
-    }
+    // ---------------------------------------------------------------------
+    // 璇存槑锛氬師 getWXCode / getDXCode / encode 涓変釜绉佹湁鏂规硶宸查殢鍙戦�佹柟涓�璧锋敹鍙e埌
+    // ruoyi-message 妯″潡锛圶inHuaMpApi / LishuiSmsSender锛夛紝姝ゅ宸插垹闄わ紝閬垮厤閲嶅瀹炵幇銆�
+    // 娉ㄦ剰锛氭湰绫荤殑 getWXCode 鍘熶娇鐢� new GsonBuilder().disableHtmlEscaping()锛�
+    //      涓� RyTask.getWXCode 鐨� new Gson() 涓嶅悓锛岃宸紓宸插湪 XinHuaMpApi 涓寜绔欑偣淇濈暀銆�
+    // ---------------------------------------------------------------------
 
     /**
      * 闅忚浠诲姟鏄惁瓒呮椂
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/SmsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/SmsController.java
index fbbb261..f11f6b6 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/SmsController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/SmsController.java
@@ -1,19 +1,17 @@
 package com.ruoyi.web.controller.common;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.gson.Gson;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.dx.MessageSend;
-import com.ruoyi.common.utils.HttpUtil;
 import com.ruoyi.common.utils.RSAPublicKeyExample;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.http.HttpUtils;
-import com.ruoyi.common.utils.sms.smsUtils;
-import com.smartor.common.MtSubmitSmUtil;
-import com.smartor.common.ShiyiSmsUtil;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
+import com.ruoyi.message.sms.provider.shiyi.ShiyiSmsRequest;
+import com.ruoyi.message.sms.provider.shiyi.ShiyiSmsResponse;
+import com.ruoyi.message.sms.provider.shiyi.ShiyiSmsUtil;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSenderFactory;
 import com.smartor.domain.*;
-import com.smartor.mapper.UtilsMapper;
 import com.smartor.service.IServiceOutPathService;
 import com.smartor.service.IServiceSubtaskService;
 import io.swagger.annotations.Api;
@@ -28,35 +26,28 @@
 import org.springframework.web.bind.annotation.RestController;
 
 import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
 
+/**
+ * 鐭ヤ俊鎺ュ彛锛堝澶栫煭淇� / 寰俊鍏紬鍙峰彂閫佸叆鍙o級銆�
+ * <p>
+ * 璇存槑锛氱煭淇′笌鍏紬鍙风殑绔欑偣宸紓锛堟姤鏂囨牸寮忋�佺鍚嶃�乼oken銆佽繑鍥炲垽瀹氾級宸插叏閮ㄦ敹鍙e埌
+ * {@code ruoyi-message} 妯″潡锛屾湰绫诲彧璐熻矗鍙傛暟缁勮涓庢寜 {@code active} 璺敱銆�
+ */
 @RestController
 @Api(description = "鐭ヤ俊鎺ュ彛")
 @RequestMapping("/sms")
 @Slf4j
 public class SmsController {
-    @Value("${xhsmsPath}")
-    private String xhsmsPath;
 
     @Autowired
-    private MtSubmitSmUtil mtSubmitSmUtil;
+    private SmsSenderFactory smsSenderFactory;
+
+    @Autowired
+    private WechatSenderFactory wechatSenderFactory;
 
     @Autowired
     private ShiyiSmsUtil shiyiSmsUtil;
-
-    @Value("${xhsmsAccount}")
-    private String xhsmsAccount;
-
-    @Value("${xhsmsPwd}")
-    private String xhsmsPwd;
-    // 铏氭嫙鎺ュ叆鐮�
-    @Value("${xhsmsjrm}")
-    private String xhsmsjrm;
 
     @Value("${localIP}")
     private String ip;
@@ -76,14 +67,16 @@
     private String active;
 
     /**
-     * @param
-     * @return
+     * 鐭俊鍙戦�侊紙娴嬭瘯锛�
      */
     @ApiOperation("鐭俊鍙戦��")
     @PostMapping("/sendTest")
     public AjaxResult send(@RequestBody smsVO vo) {
-        String sendMsg = smsUtils.sendSms(xhsmsPath, xhsmsAccount, xhsmsPwd, vo.getPhone(), vo.getContent());
-        return AjaxResult.success(sendMsg);
+        //涓庡師瀹炵幇涓�鑷达細娴嬭瘯鎺ュ彛鍥哄畾璧板競涓�锛坰msUtils.sendSms锛屽惔灞辩鍚嶏級
+        SmsSendRequest request = SmsSendRequest.of(vo.getPhone(), vo.getContent());
+        request.setCampus("2");
+        SendResult sendResult = smsSenderFactory.send("hzszlyy", request);
+        return AjaxResult.success(sendResult.getRawResponse());
     }
 
     @ApiOperation("甯備竴HIS鐭俊XML娴嬭瘯")
@@ -99,8 +92,7 @@
     }
 
     /**
-     * @param
-     * @return
+     * 鐭俊鍙戦��
      */
     @ApiOperation("鐭俊鍙戦��")
     @PostMapping("/send")
@@ -137,55 +129,14 @@
 
         String sendMsg = "false";
         try {
-            if (active.equals("hzszlyy")) {
-                sendMsg = smsUtils.sendSms(xhsmsPath, xhsmsAccount, xhsmsPwd, vo.getPhone(), content);
-            } else if (active.equals("nhfy")) {
-                Map<String, Object> smsResult = mtSubmitSmUtil.submitSm(vo.getPhone(), content);
-                if (smsResult != null && smsResult.get("result") != null && smsResult.get("result").toString().equals("0")) {
-                    sendMsg = "true";
-                }
-            } else if (active.equals("sltd")) {
-                String data = MessageSend.sendMsg(content, "6", vo.getPhone(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
-                if (StringUtils.isNotEmpty(data)) {
-                    ObjectMapper mapper = new ObjectMapper();
-                    JsonNode root = mapper.readTree(data);
-                    String status = root.get("result").get(0).get("status").asText();
-                    if (status.equals("00000")) {
-                        sendMsg = "true";
-                    }
-                }
-            } else if (active.equals("xh")) {
-//                Map<String, String> req = new HashMap<>();
-//                req.put("phone", vo.getPhone());
-//                req.put("content", vo.getContent());
-//                Boolean result = HttpUtil.postJsonRequest(xhsmsPath, new Gson().toJson(req));
-                Map<String, String> map2 = new HashMap<String, String>();
-                map2.put("action", "send");
-                map2.put("account", xhsmsAccount);
-                map2.put("password", xhsmsPwd);
-                map2.put("mobile", vo.getPhone());
-                map2.put("content", vo.getContent());
-                map2.put("extno", xhsmsjrm);
-                map2.put("rt", "json");
-                StringBuilder encodedParams = new StringBuilder();
-
-                for (Map.Entry<String, String> entry : map2.entrySet()) {
-                    if (encodedParams.length() > 0) {
-                        encodedParams.append("&");
-                    }
-                    // 瀵归敭鍜屽�艰繘琛孶RL缂栫爜
-                    String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
-                    String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
-                    encodedParams.append(encodedKey).append("=").append(encodedValue);
-                }
-                Boolean result = HttpUtils.sendPost(xhsmsPath, encodedParams.toString());
-                if (result) {
-                    sendMsg = "true";
-                }
-            } else if (active.equals("ls")) {
-                //涓芥按13瀹跺尰闄紝鏈夌偣涓嶆柟渚匡紝鏈夌┖鍐嶆帴
+            if ("ls".equals(active)) {
+                //涓庡師瀹炵幇涓�鑷达細涓芥按13瀹跺尰闄㈢殑鐭俊鍔熻兘鏍囪涓烘湭寮�閫�
                 return AjaxResult.error("璇ョ煭淇″姛鑳借繕鏈紑閫�");
             }
+            SmsSendRequest request = SmsSendRequest.of(vo.getPhone(), content, vo.getOrgid());
+            //甯備竴鍖哄垎婀栨花/鍚村北绛惧悕锛屾鎺ュ彛鏃犻櫌鍖轰俊鎭紝涓庡師瀹炵幇涓�鑷达紙闈炴箹婊ㄥ嵆鍚村北锛�
+            SendResult sendResult = smsSenderFactory.send(active, request);
+            sendMsg = sendResult.asLegacyFlag();
             log.info(sendMsg);
         } catch (Exception ex) {
             log.error(ex.getMessage());
@@ -194,8 +145,7 @@
     }
 
     /**
-     * @param
-     * @return
+     * 寰俊鍙戦��
      */
     @ApiOperation("寰俊鍙戦��")
     @PostMapping("/sendChat")
@@ -223,14 +173,20 @@
             serviceOutPath.setOrgid(vo.getOrgid());
             iServiceOutPathService.insertServiceOutPath(serviceOutPath);
             String url = StringUtils.isNotEmpty(req_path) ? ip + ":" + req_path + "/wt?p=" + format : ip + "/wt?p=" + format;
-            sendMsg = smsUtils.sendChat(url, vo.getPhone(), vo.getIdCard());
+            //涓庡師瀹炵幇涓�鑷达細璇ユ帴鍙e浐瀹氳蛋甯備竴鍏紬鍙�
+            WechatSendRequest request = new WechatSendRequest();
+            request.setIdCard(vo.getIdCard());
+            request.setPhone(vo.getPhone());
+            request.setUrl(url);
+            request.setOrgid(vo.getOrgid());
+            SendResult sendResult = wechatSenderFactory.send("hzszlyy", request);
+            sendMsg = sendResult.getRawResponse();
         }
         return AjaxResult.success(sendMsg);
     }
 
     /**
-     * @param
-     * @return
+     * 鐢熸垚澶栭摼
      */
     @ApiOperation("鐢熸垚澶栭摼")
     @PostMapping("/getUrl")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSLTDHealthcareRecordController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSLTDHealthcareRecordController.java
index 363f367..a297da7 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSLTDHealthcareRecordController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSLTDHealthcareRecordController.java
@@ -2,8 +2,6 @@
 
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.smartor.common.MtSubmitSmUtil;
-import com.smartor.domain.MtSubmitSmResp;
 import com.smartor.domain.ServiceSLTDDeptReqVO;
 import com.smartor.domain.ServiceSLTDInhospReqVO;
 import com.smartor.domain.ServiceSLTDInhospResDTO;
@@ -31,9 +29,6 @@
 
     @Autowired
     private IServiceSLTDHealthcareRecordService serviceSLTDHealthcareRecordService;
-
-    @Autowired
-    private MtSubmitSmUtil mtSubmitSmUtil;
 
     /**
      * 鏌ヨ鍦ㄩ櫌鎮h�呭仴搴疯褰曞垪琛�
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceTelInfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceTelInfoController.java
index dd17bab..218c099 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceTelInfoController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceTelInfoController.java
@@ -1,7 +1,6 @@
 package com.ruoyi.web.controller.smartor;
 
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.common.utils.sms.smsUtils;
 import com.smartor.domain.smsVO;
 import com.smartor.service.IServiceTaskoperService;
 import com.smartor.service.IServiceTelInfoService;
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ShiyiSmsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ShiyiSmsController.java
index 5b1050c..7857b72 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ShiyiSmsController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ShiyiSmsController.java
@@ -5,9 +5,9 @@
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.enums.BusinessType;
-import com.smartor.common.ShiyiSmsUtil;
-import com.smartor.domain.ShiyiSmsRequest;
-import com.smartor.domain.ShiyiSmsResponse;
+import com.ruoyi.message.sms.provider.shiyi.ShiyiSmsRequest;
+import com.ruoyi.message.sms.provider.shiyi.ShiyiSmsResponse;
+import com.ruoyi.message.sms.provider.shiyi.ShiyiSmsUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/BaseSmsaccountController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/BaseSmsaccountController.java
index b7c8ec7..eae6887 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/BaseSmsaccountController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/tools/BaseSmsaccountController.java
@@ -11,8 +11,9 @@
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.poi.ExcelUtil;
-import com.ruoyi.common.utils.sms.smsUtils;
-import com.smartor.common.MtSubmitSmUtil;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
 import com.smartor.domain.BaseSmsRequest;
 import com.smartor.domain.BaseSmsaccount;
 import com.smartor.domain.BatchBaseSmsRequest;
@@ -43,20 +44,14 @@
     @Autowired
     private IBaseSmsaccountService baseSmsaccountService;
 
-    @Value("${xhsmsPath}")
-    private String xhsmsPath;
-
-    @Value("${xhsmsAccount}")
-    private String xhsmsAccount;
-
-    @Value("${xhsmsPwd}")
-    private String xhsmsPwd;
-
     @Value("${spring.profiles.active}")
     private String active;
 
+    /**
+     * 娑堟伅鍙戦�佹柟宸ュ巶锛堢煭淇★級锛屾浛浠e師鏉ョ洿鎺ユ敞鍏� xhsms* 閰嶇疆 + 鍚勭珯鐐瑰垎鏀殑鍐欐硶
+     */
     @Autowired
-    private MtSubmitSmUtil mtSubmitSmUtil;
+    private SmsSenderFactory smsSenderFactory;
 
     /**
      * 鏌ヨ鐭俊璐﹀彿鍒楄〃
@@ -135,14 +130,19 @@
             try {
                 JSONObject jsTemp = JSON.parseObject(baseSmsRequest.getTemplateParam());
                 String content = jsTemp.getString("name");
-                sendMsg = smsUtils.sendSms(xhsmsPath, xhsmsAccount, xhsmsPwd, baseSmsRequest.getPhoneNumber(), content);
+                //鐭俊鍙戦�佸凡鏀跺彛鍒� ruoyi-message 妯″潡锛涘師瀹炵幇璋冪敤鐨勬槸 smsUtils.sendSms锛堝惔灞辩鍚嶏級
+                SmsSendRequest request = SmsSendRequest.of(baseSmsRequest.getPhoneNumber(), content);
+                request.setCampus("2");
+                SendResult sendResult = smsSenderFactory.send("hzszlyy", request);
+                sendMsg = sendResult.getRawResponse();
             } catch (Exception ex) {
                 return AjaxResult.error(ex.getMessage());
             }
             return AjaxResult.success(sendMsg);
         } else if (active.equals("nhfy")) {
-            Map<String, Object> smsResult = mtSubmitSmUtil.submitSm(baseSmsRequest.getPhoneNumber(), baseSmsRequest.getTemplateCode());
-            return AjaxResult.success(smsResult.get("result"));
+            SmsSendRequest request = SmsSendRequest.of(baseSmsRequest.getPhoneNumber(), baseSmsRequest.getTemplateCode());
+            SendResult sendResult = smsSenderFactory.send("nhfy", request);
+            return AjaxResult.success(sendResult.getCode());
 
         } else {
             if (baseSmsaccountService.sendMsg(baseSmsRequest) == null) {
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/WeChatService.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/WeChatService.java
deleted file mode 100644
index 2492d50..0000000
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/test/WeChatService.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.ruoyi.web.test;
-
-import com.alibaba.fastjson2.JSONArray;
-import com.alibaba.fastjson2.JSONObject;
-import com.smartor.domain.WeChatSendVo;
-import me.chanjar.weixin.common.exception.WxErrorException;
-import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
-import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
-import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
-import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
-import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class WeChatService {
-    private WxMpService wxMpService;
-
-    public WeChatService(String appId, String appSecret) {
-        wxMpService = new WxMpServiceImpl();
-        wxMpService.setWxMpConfigStorage(new WxMpInMemoryConfigStorage());
-        WxMpInMemoryConfigStorage wxMpConfigStorage = (WxMpInMemoryConfigStorage) wxMpService.getWxMpConfigStorage();
-        wxMpConfigStorage.setAppId(appId);
-        wxMpConfigStorage.setSecret(appSecret);
-    }
-
-    public void sendMessageToFollowers(String messageContent) {
-        try {
-            // 鑾峰彇鎵�鏈夊叧娉ㄨ�呯殑OpenID鍒楄〃
-            List<String> openIdList = wxMpService.getUserService().userList(null).getOpenids();
-            for (String openId : openIdList) {
-                WxMpKefuMessage wxMpKefuMessage = WxMpKefuMessage.TEXT().toUser(openId).content("鍒╂箹鍏紬鍙锋祴璇�").build();
-//                try {
-//                    boolean b = wxMpService.getKefuService().sendKefuMessage(wxMpKefuMessage);
-//                    if(b==false){
-//                        continue;
-//                    }
-//                }catch (WxErrorException e){
-//                    continue;
-//                }
-
-                WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder().toUser(openId).templateId("oG3pJHPVWpE81DmZsua_2tKwgJ97r0qz37z56ns7NB4").url("www.baidu.com").build();
-                templateMessage.addData(new WxMpTemplateData("{first", "浣犲ソ锛屾牴鎹綘鐨勮褰曚俊鎭紝涓轰綘鐢熸垚杩戞湡鐨勫悍澶嶆姤鍛�", "#FFB6C1"));
-                templateMessage.addData(new WxMpTemplateData("keyword1", "2023-05-15-2023-05-16", "#B95EA6"));
-                templateMessage.addData(new WxMpTemplateData("keyword2", "鍏辨祴閲忚绯�10娆★紝鍏朵腑姝e父7娆°�佸亸楂�2娆°�佸亸浣�1娆★紱骞冲潎姣忔棩楗鎽勫叆鐑噺1578澶у崱锛屽湪姣忔棩鐑噺鎺у埗鑼冨洿鍐咃紱骞冲潎姣忔棩鏁f1灏忔椂锛屾弧瓒冲悍澶嶉渶瑕�", "#173177"));
-                templateMessage.addData(new WxMpTemplateData("remark", "213456", "#87cefa"));
-//                templateMessage.addData(new WxMpTemplateData("low","AA","#FF6347"));
-//                templateMessage.addData(new WxMpTemplateData("scq_day","AA","#FF1493"));
-//                templateMessage.addData(new WxMpTemplateData("bir_day","AA","#FF00FF" ));
-//                templateMessage.addData(new WxMpTemplateData("daily_english_cn","AA","#800080"));
-//                templateMessage.addData(new WxMpTemplateData("daily_english_en","AA","#FFA500"));
-                wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
-            }
-        } catch (WxErrorException e) {
-            e.printStackTrace();
-        }
-    }
-
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/MessageSend.java b/ruoyi-common/src/main/java/com/ruoyi/common/dx/MessageSend.java
deleted file mode 100644
index fdf267a..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/MessageSend.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package com.ruoyi.common.dx;
-
-import com.dingtalk.api.DefaultDingTalkClient;
-import com.dingtalk.api.DingTalkClient;
-import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
-import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
-import com.ruoyi.common.utils.uuid.UUID;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 鐪佺珛鍚屽痉淇℃伅鍙戦�佹帴鍙�
- */
-@Slf4j
-public class MessageSend {
-    /**
-     * //     * @param sServiceNumber  鍘傚璁稿彲
-     * //     * @param sTemplateNumber 妯℃澘璁稿彲
-     * //     * @param sOrderNo        鎮h�呭敮涓�鍙风爜
-     * //     * @param sMessageContent 鐭俊鍐呭
-     *
-     * @param sMessageType  鐭俊绫诲瀷   1=楠岃瘉鐮併��2=閫氱煡銆�3=骞垮憡 6=鍐呭鏈夐摼鎺ュ拰鐢佃瘽锛�7=閽夐拤娑堟伅
-     * @param sUserNumber   鎵嬫満鍙风爜
-     * @param sScheduleTime 棰勭害鍙戦�佹椂闂�
-     * @return
-     */
-    public static String sendMsg(String sMessageContent, String sMessageType, String sUserNumber, String sScheduleTime) {
-        log.info("--sMessageContent 鐨勫�间负锛歿}   ,--sMessageType 鐨勫�间负锛歿},   --sUserNumber 鐨勫�间负锛歿},   --sScheduleTime 鐨勫�间负:{}", sMessageContent, sMessageType, sUserNumber, sScheduleTime);
-
-        com.ruoyi.common.dx.SmsService service = new SmsService();
-        SmsServiceSoap soap = service.getSmsServiceSoap();
-        String result = null;
-
-        try {
-            if ("6".equals(sMessageType)) {
-                result = soap.i5GSend("202508291634227086", "T202508291635259440", UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
-                log.info("----鐭俊杩斿洖鐨勬暟鎹负锛歿},    ----sMessageContent 鐨勫�间负:{}", result,UUID.randomUUID().toString());
-            } else if ("7".equals(sMessageType)) {
-                result = soap.i5GSend("202508291634227086", "T202607211306131891",
-                        UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
-                log.info("----閽夐拤杩斿洖鐨勫師濮嬫暟鎹负锛歿}", result);
-
-            } else {
-                log.warn("涓嶆敮鎸佺殑鐭俊绫诲瀷锛歿}", sMessageType);
-            }
-        } catch (Exception e) {
-            log.error("瀹屾暣閿欒淇℃伅锛歿}", e.getCause().getMessage());
-        }
-
-        return result;
-    }
-}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sms/smsUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/sms/smsUtils.java
deleted file mode 100644
index d650902..0000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/sms/smsUtils.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.ruoyi.common.utils.sms;
-
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.ruoyi.common.utils.HttpUtil;
-import com.ruoyi.common.utils.http.HttpUtils;
-import com.ruoyi.common.utils.sign.Md5Utils;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-@Slf4j
-public class smsUtils {
-
-
-    /**
-     * 鏉窞甯備竴鍖婚櫌鍚村北闄㈠尯鎴戠煭淇℃帴鍙�
-     *
-     * @param url      鐭俊URL
-     * @param userName 鐭俊甯愬彿
-     * @param content  鐭俊瀵嗙爜
-     * @param phone    鎵嬫満鍙风粍鍚堝 13500000001,13500000002
-     * @param content  鐭俊鍐呭
-     * @return 涓や釜鍙傛暟鐨勫拰
-     */
-    public static String sendSms(String url, String userName, String passWord, String phone, String content) {
-        long timestamp = new Date().getTime();
-        String sign = Md5Utils.hash(userName + timestamp + Md5Utils.hash(passWord));
-        content = "銆愭澀宸炲競鑲跨槫鍖婚櫌銆�" + content;
-        String jsonMsg = "{" +
-                "\"userName\": \"" + userName + "\"," +
-                "\"content\": \"" + content + "\"," +
-                "\"phoneList\": [" + phone + "]," +
-                "\"timestamp\": " + timestamp + "," +
-                "\"sign\": \"" + sign + "\"" +
-                "}";
-        Boolean sendMsg=HttpUtil.postJsonRequest(url, jsonMsg);
-        return sendMsg.toString();
-
-    }
-
-
-    /**
-     * 鏉窞甯備竴鍖婚櫌婀栨花闄㈠尯鎴戠煭淇℃帴鍙�
-     *
-     * @param url      鐭俊URL
-     * @param userName 鐭俊甯愬彿
-     * @param content  鐭俊瀵嗙爜
-     * @param phone    鎵嬫満鍙风粍鍚堝 13500000001,13500000002
-     * @param content  鐭俊鍐呭
-     * @return 涓や釜鍙傛暟鐨勫拰
-     */
-    public static String sendSms1(String url, String userName, String passWord, String phone, String content) {
-        long timestamp = new Date().getTime();
-        String sign = Md5Utils.hash(userName + timestamp + Md5Utils.hash(passWord));
-        content = "銆愭澀宸炲競绗竴浜烘皯鍖婚櫌銆�" + content;
-        String jsonMsg = "{" +
-                "\"userName\": \"" + userName + "\"," +
-                "\"content\": \"" + content + "\"," +
-                "\"phoneList\": [" + phone + "]," +
-                "\"timestamp\": " + timestamp + "," +
-                "\"sign\": \"" + sign + "\"" +
-                "}";
-        Boolean sendMsg=HttpUtil.postJsonRequest(url, jsonMsg);
-        return sendMsg.toString();
-
-    }
-
-    /**
-     * 鏉窞甯備竴鍖婚櫌鍚村北闄㈠尯寰俊鎺ュ彛
-     *
-     * @param url      寰俊URL
-     * @param phone    鎵嬫満鍙� 13500000001
-     * @param idCard  韬唤璇�
-     * @return 涓や釜鍙傛暟鐨勫拰
-     */
-    public static String sendChat(String url,String phone,String idCard){
-        String urlTemp = "http://192.200.54.14:5003/sfjk/SendMessage?sfzh="
-                + idCard
-                + "&title=鎮ㄥソ锛岄個璇锋偍濉啓鍑洪櫌璋冩煡琛紝璇风偣鍑诲~鍐欍��&content=寰呴殢璁�&phone=" + phone
-                + "&url=" + url + "&key=ff76f8904f5f32b5ee1739e8ea46e60g";
-        String sendMsg = "";
-        try {
-            log.info("銆恠endChat銆戝競涓�寰俊鍏紬鍙疯姹傚弬鏁帮細{}", urlTemp);
-            sendMsg = HttpUtils.sendPost(urlTemp);
-            log.info("銆恠endChat銆戝競涓�寰俊鍏紬鍙疯繑鍥炲�硷細{}", sendMsg);
-        } catch (Exception ex) {
-            sendMsg=ex.getMessage();
-            log.error(ex.getMessage());
-        }
-        return  sendMsg;
-    }
-}
diff --git a/ruoyi-message/pom.xml b/ruoyi-message/pom.xml
new file mode 100644
index 0000000..4fc174b
--- /dev/null
+++ b/ruoyi-message/pom.xml
@@ -0,0 +1,100 @@
+<?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">
+    <parent>
+        <artifactId>ruoyi</artifactId>
+        <groupId>com.ruoyi</groupId>
+        <version>3.8.5</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-message</artifactId>
+
+    <description>
+        娑堟伅鍙戦�佹ā鍧楋細鐭俊銆佸井淇″叕浼楀彿绛夊彂閫佹柟缁熶竴鏀跺彛
+    </description>
+
+    <dependencies>
+        <!-- 閫氱敤宸ュ叿锛欻ttpUtil / HttpUtils / OkHttpExample / StringUtils / Md5Utils 绛� -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common</artifactId>
+        </dependency>
+
+        <!-- lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.34</version>
+        </dependency>
+
+        <!-- fastjson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.41</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+        </dependency>
+
+        <!-- gson -->
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+
+        <!-- jackson -->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+
+        <!-- 寰俊鍏紬鍙� SDK锛圵xMpUtils锛� -->
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-mp</artifactId>
+            <version>3.0.0</version>
+        </dependency>
+
+        <!-- 鐪佺珛鍚屽痉鐭俊锛欰pache Axis锛圵SDL 鐢熸垚瀹㈡埛绔級 -->
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.axis</groupId>
+            <artifactId>axis-jaxrpc</artifactId>
+            <version>1.4</version>
+        </dependency>
+
+        <!-- 涓芥按鐭俊锛歄kHttp -->
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.10.0</version>
+        </dependency>
+
+        <!-- 闃块噷浜戠煭淇� SDK -->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>dysmsapi20170525</artifactId>
+            <version>2.0.24</version>
+        </dependency>
+
+        <!-- 宸ュ叿 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.4</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/MessageChannel.java b/ruoyi-message/src/main/java/com/ruoyi/message/MessageChannel.java
new file mode 100644
index 0000000..5d399a3
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/MessageChannel.java
@@ -0,0 +1,37 @@
+package com.ruoyi.message;
+
+/**
+ * 娑堟伅鍙戦�佹笭閬撶被鍨嬨��
+ */
+public enum MessageChannel {
+
+    /**
+     * 鐭俊
+     */
+    SMS("4", "鐭俊"),
+
+    /**
+     * 寰俊鍏紬鍙�
+     */
+    WECHAT("5", "寰俊鍏紬鍙�");
+
+    private final String preachformCode;
+
+    private final String desc;
+
+    MessageChannel(String preachformCode, String desc) {
+        this.preachformCode = preachformCode;
+        this.desc = desc;
+    }
+
+    /**
+     * 瀵瑰簲 ServiceSubtaskPreachform / ServiceFromEnum 閲岀殑鍙戦�佹柟寮忕紪鐮侊紙4=鐭俊锛�5=鍏紬鍙凤級
+     */
+    public String getPreachformCode() {
+        return preachformCode;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/SendException.java b/ruoyi-message/src/main/java/com/ruoyi/message/SendException.java
new file mode 100644
index 0000000..438ad3c
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/SendException.java
@@ -0,0 +1,46 @@
+package com.ruoyi.message;
+
+/**
+ * 鍙戦�佹柟寮傚父銆�
+ * <p>
+ * 鏃т唬鐮佸湪鍙戦�佸け璐ユ椂鐩存帴鎶� {@code new BaseException("鐭俊鍙戦�佸け璐�")}锛屼负浜嗕繚鎸佽涓轰竴鑷达紝
+ * 鏈ā鍧楁彁渚涘悓璇箟鐨勮繍琛屾椂寮傚父锛岀敱璋冪敤鏂瑰喅瀹氭槸鍚﹁浆鎹€��
+ */
+public class SendException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鍙戦�佹柟 key
+     */
+    private final String senderKey;
+
+    /**
+     * 绗笁鏂瑰師濮嬪搷搴�
+     */
+    private final String rawResponse;
+
+    public SendException(String message) {
+        this(null, message, null);
+    }
+
+    public SendException(String senderKey, String message, String rawResponse) {
+        super(message);
+        this.senderKey = senderKey;
+        this.rawResponse = rawResponse;
+    }
+
+    public SendException(String senderKey, String message, String rawResponse, Throwable cause) {
+        super(message, cause);
+        this.senderKey = senderKey;
+        this.rawResponse = rawResponse;
+    }
+
+    public String getSenderKey() {
+        return senderKey;
+    }
+
+    public String getRawResponse() {
+        return rawResponse;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/SendResult.java b/ruoyi-message/src/main/java/com/ruoyi/message/SendResult.java
new file mode 100644
index 0000000..bc241a3
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/SendResult.java
@@ -0,0 +1,159 @@
+package com.ruoyi.message;
+
+import java.io.Serializable;
+
+/**
+ * 缁熶竴鍙戦�佺粨鏋溿��
+ * <p>
+ * 鍚勭珯鐐瑰師濮嬪疄鐜扮敤瀛楃涓叉爣璁帮紙濡� {@code "true"} / {@code "success"} / {@code Boolean}锛夎〃绀烘垚璐ワ紝
+ * 璋冪敤鏂瑰悇鑷В鏋愮涓夋柟杩斿洖鏍煎紡锛屽鏄撳嚭閿欍�傛湰绫绘妸銆屾槸鍚︽垚鍔� + 娓犻亾 + 绗笁鏂瑰師濮嬬爜 + 鍘熷鍝嶅簲銆嶇粺涓�鏀跺彛銆�
+ * <p>
+ * 娉ㄦ剰锛歿@link #ok} 涓� false 鏃讹紝{@link #message} 宸茬粡鍖呭惈鍙洿鎺ュ啓鍏ラ殢璁垮瓙浠诲姟 remark 鐨勪腑鏂囨弿杩帮紝
+ * 浣嗕负浜嗕繚鎸佸悇绔欑偣绾夸笂琛屼负涓嶅彉锛岃皟鐢ㄦ柟浠嶅彲娌跨敤鍘熸湁 remark 鏂囨銆�
+ */
+public class SendResult implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鏄惁鍙戦�佹垚鍔�
+     */
+    private boolean ok;
+
+    /**
+     * 娓犻亾绫诲瀷锛氱煭淇� / 寰俊鍏紬鍙�
+     */
+    private MessageChannel channelType;
+
+    /**
+     * 鍏蜂綋鍙戦�佹柟 key锛屼緥濡� xh / ls / sltd / nhfy / hzszlyy
+     */
+    private String senderKey;
+
+    /**
+     * 绗笁鏂硅繑鍥炵殑涓氬姟鐮侊紙鏈夊氨甯︿笂锛屾病鏈変负 null锛夛紝渚嬪涓芥按鐨� Code銆佸競涓�鐨� code
+     */
+    private String code;
+
+    /**
+     * 澶辫触鍘熷洜 / 琛ュ厖璇存槑
+     */
+    private String message;
+
+    /**
+     * 绗笁鏂瑰師濮嬪搷搴旓紝渚夸簬鎺掓煡
+     */
+    private String rawResponse;
+
+    public SendResult() {
+    }
+
+    /**
+     * 鏋勯�犳垚鍔熺粨鏋�
+     */
+    public static SendResult success(String senderKey, MessageChannel channelType, String rawResponse) {
+        SendResult result = new SendResult();
+        result.ok = true;
+        result.senderKey = senderKey;
+        result.channelType = channelType;
+        result.rawResponse = rawResponse;
+        return result;
+    }
+
+    /**
+     * 鏋勯�犲け璐ョ粨鏋�
+     */
+    public static SendResult fail(String senderKey, MessageChannel channelType, String message, String rawResponse) {
+        SendResult result = new SendResult();
+        result.ok = false;
+        result.senderKey = senderKey;
+        result.channelType = channelType;
+        result.message = message;
+        result.rawResponse = rawResponse;
+        return result;
+    }
+
+    /**
+     * 琛ュ厖绗笁鏂逛笟鍔$爜锛岃繑鍥炶嚜韬究浜庨摼寮忚皟鐢�
+     */
+    public SendResult withCode(String code) {
+        this.code = code;
+        return this;
+    }
+
+    /**
+     * 琛ュ厖璇存槑淇℃伅锛岃繑鍥炶嚜韬究浜庨摼寮忚皟鐢�
+     */
+    public SendResult withMessage(String message) {
+        this.message = message;
+        return this;
+    }
+
+    /**
+     * 杩斿洖涓庢棫浠g爜绛変环鐨勫竷灏旀爣璁帮紝渚夸簬娓愯繘寮忔浛鎹�
+     *
+     * @return 鎴愬姛杩斿洖 "true"锛屽け璐ヨ繑鍥� "false"
+     */
+    public String asLegacyFlag() {
+        return ok ? "true" : "false";
+    }
+
+    public boolean isOk() {
+        return ok;
+    }
+
+    public void setOk(boolean ok) {
+        this.ok = ok;
+    }
+
+    public MessageChannel getChannelType() {
+        return channelType;
+    }
+
+    public void setChannelType(MessageChannel channelType) {
+        this.channelType = channelType;
+    }
+
+    public String getSenderKey() {
+        return senderKey;
+    }
+
+    public void setSenderKey(String senderKey) {
+        this.senderKey = senderKey;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getRawResponse() {
+        return rawResponse;
+    }
+
+    public void setRawResponse(String rawResponse) {
+        this.rawResponse = rawResponse;
+    }
+
+    @Override
+    public String toString() {
+        return "SendResult{ok=" + ok
+                + ", channelType=" + channelType
+                + ", senderKey='" + senderKey + '\''
+                + ", code='" + code + '\''
+                + ", message='" + message + '\''
+                + ", rawResponse='" + rawResponse + '\''
+                + '}';
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/config/AliyunSmsConfig.java b/ruoyi-message/src/main/java/com/ruoyi/message/config/AliyunSmsConfig.java
new file mode 100644
index 0000000..dcedc2c
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/config/AliyunSmsConfig.java
@@ -0,0 +1,28 @@
+package com.ruoyi.message.config;
+
+import lombok.Data;
+
+/**
+ * 闃块噷浜戠煭淇¢厤缃紙aliyun 閫氶亾锛夈��
+ * <p>
+ * 鐢� {@link MessageProperties#getSms()} 浠� {@link RootMessageProperties} 鐨勬墎骞冲瓧娈电粍瑁呰�屾潵锛�
+ * 瀛楁涓� yml key 鐨勫搴斿叧绯伙細{@code accessKeyId} / {@code accessKeySecret} / {@code signName}銆�
+ */
+@Data
+public class AliyunSmsConfig {
+
+    /**
+     * 瀵瑰簲 yml key {@code accessKeyId}
+     */
+    private String accessKeyId;
+
+    /**
+     * 瀵瑰簲 yml key {@code accessKeySecret}
+     */
+    private String accessKeySecret;
+
+    /**
+     * 瀵瑰簲 yml key {@code signName}
+     */
+    private String signName;
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/config/MessageConfigValidator.java b/ruoyi-message/src/main/java/com/ruoyi/message/config/MessageConfigValidator.java
new file mode 100644
index 0000000..cf26955
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/config/MessageConfigValidator.java
@@ -0,0 +1,94 @@
+package com.ruoyi.message.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * 娑堟伅鍙戦�侀厤缃嚜妫�銆�
+ * <p>
+ * 瀛樺湪鐨勬剰涔夛細杩欎簺 key 杩囧幓鏄暎钀藉湪鍚勫鐨� {@code @Value}锛屾敼鎴� {@code @ConfigurationProperties}
+ * 涔嬪悗濡傛灉鍓嶇紑/灞傜骇鍐欓敊锛�**缂栬瘧鏈熷畬鍏ㄥ彂鐜颁笉浜�**锛岀洿鍒扮嚎涓婂彂鐭俊鏃舵墠鍙戠幇鍙傛暟鏄� null銆�
+ * 鍥犳鍚姩鏃舵妸褰撳墠 profile 鐪熸鐢ㄥ埌鐨勯厤缃」鎵撳嵃鍑烘潵锛堝瘑閽ヨ劚鏁忥級锛屽苟瀵圭┖鍊煎憡璀︺��
+ */
+@Slf4j
+@Component
+public class MessageConfigValidator implements ApplicationRunner {
+
+    private final MessageProperties properties;
+
+    @Value("${spring.profiles.active:}")
+    private String active;
+
+    public MessageConfigValidator(MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    public void run(ApplicationArguments args) {
+        MessageProperties.Sms sms = properties.getSms();
+        XhsmsConfig xhsms = sms.getXhsms();
+        MtSmsConfig mt = sms.getMt();
+        AliyunSmsConfig aliyun = sms.getAliyun();
+
+        log.info("銆愭秷鎭厤缃嚜妫�銆慳ctive={}锛寈hsms: path={}, account={}, pwd={}, extno={}",
+                active, mask(xhsms.getPath()), mask(xhsms.getAccount()), maskSecret(xhsms.getPwd()),
+                mask(xhsms.getExtno()));
+        log.info("銆愭秷鎭厤缃嚜妫�銆憁t(nhfy): url={}, accountName={}, password={}, sourceAddr={}, serviceCode={}, appkey={}, flag={}",
+                mask(mt.getUrl()), mask(mt.getAccountName()), maskSecret(mt.getPassword()),
+                mask(mt.getSourceAddr()), mask(mt.getServiceCode()), mask(mt.getAppkey()), mask(mt.getFlag()));
+        log.info("銆愭秷鎭厤缃嚜妫�銆慳liyun: accessKeyId={}, accessKeySecret={}, signName={}",
+                mask(aliyun.getAccessKeyId()), maskSecret(aliyun.getAccessKeySecret()), mask(aliyun.getSignName()));
+        log.info("銆愭秷鎭厤缃嚜妫�銆憌echat: shiyi.url={}, shiyi.key={}, xinhua.service={}",
+                mask(properties.getWechat().getShiyi().getUrl()),
+                maskSecret(properties.getWechat().getShiyi().getKey()),
+                mask(properties.getWechat().getXinhua().getService()));
+
+        check("active", active);
+        if ("xh".equals(active) || "hzszlyy".equals(active)) {
+            check("xhsmsPath", xhsms.getPath());
+            check("xhsmsAccount", xhsms.getAccount());
+            check("xhsmsPwd", xhsms.getPwd());
+        } else if ("nhfy".equals(active)) {
+            check("sms_url", mt.getUrl());
+            check("sms_accountName", mt.getAccountName());
+            check("sms_password", mt.getPassword());
+            check("sms_sourceAddr", mt.getSourceAddr());
+            check("sms_serviceCode", mt.getServiceCode());
+            check("sms_flag", mt.getFlag());
+        }
+    }
+
+    private void check(String key, String value) {
+        if (value == null || value.trim().isEmpty()) {
+            log.warn("銆愭秷鎭厤缃嚜妫�銆戔殸锔� 褰撳墠 profile锛坽}锛夐渶瑕� {}锛屼絾璇ラ厤缃负绌�/鏈粦瀹氾紒"
+                    + "璇锋鏌� application-{}.yml 涓� MessageProperties/RootMessageProperties 鐨勭粦瀹氬眰绾с��",
+                    active, key, active);
+        }
+    }
+
+    private String mask(String value) {
+        if (value == null) {
+            return "<null>";
+        }
+        if (value.isEmpty()) {
+            return "<绌�>";
+        }
+        return value;
+    }
+
+    private String maskSecret(String value) {
+        if (value == null) {
+            return "<null>";
+        }
+        if (value.isEmpty()) {
+            return "<绌�>";
+        }
+        if (value.length() <= 2) {
+            return "**";
+        }
+        return value.substring(0, 1) + "***" + value.substring(value.length() - 1);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/config/MessageProperties.java b/ruoyi-message/src/main/java/com/ruoyi/message/config/MessageProperties.java
new file mode 100644
index 0000000..a47d745
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/config/MessageProperties.java
@@ -0,0 +1,222 @@
+package com.ruoyi.message.config;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 娑堟伅鍙戦�佹ā鍧楅厤缃紙缁熶竴鍏ュ彛锛夈��
+ * <p>
+ * 鐢变袱鍧楁嫾鎴愶紝<b>涓嶈鍚堝苟</b>锛�
+ * <ul>
+ *   <li>瀛橀噺閰嶇疆锛坽@code xhsmsPath} / {@code sms_accountName} / {@code accessKeyId} / {@code signName} ...锛�
+ *       鈫� {@link RootMessageProperties}锛屽瓧娈靛悕涓� yml key 瀹屽叏鍚屽悕锛�</li>
+ *   <li>鏂板椤癸紙鍘熷厛纭紪鐮佸湪浠g爜閲屻�佹湰娆℃彁涓哄彲閰嶇疆鐨勫湴鍧�/瀵嗛挜/鏂囨锛夆啋 鏈被鐨�
+ *       {@code message.sms.*} / {@code message.wechat.*} 鍓嶇紑椤广��</li>
+ * </ul>
+ * 瀵逛笟鍔′唬鐮佸彧鏆撮湶鍒嗙粍鐨� {@code getSms()} / {@code getWechat()}锛屽睆钄戒袱绉嶇粦瀹氱殑宸紓銆�
+ * <p>
+ * 鈿狅笍 {@code getSms()} 鏄墜鍐� getter锛屾瘡娆¤皟鐢ㄤ細鎶婂瓨閲忔墎骞冲瓧娈靛悎骞惰繘鍒嗙粍瀵硅薄锛涜繖鏄箓绛夌殑锛�
+ * 鍥犳鍗充娇琚皟鐢ㄥ娆′篃娌℃湁鍓綔鐢ㄣ��
+ */
+@Component
+@ConfigurationProperties(prefix = "message")
+public class MessageProperties {
+
+    private final RootMessageProperties root;
+
+    /** 缁戝畾 {@code message.sms.*} */
+    private Sms sms = new Sms();
+
+    /** 缁戝畾 {@code message.wechat.*} */
+    private Wechat wechat = new Wechat();
+
+    @Autowired
+    public MessageProperties(RootMessageProperties root) {
+        this.root = root;
+    }
+
+    public RootMessageProperties getRoot() {
+        return root;
+    }
+
+    /**
+     * 鐭俊閰嶇疆缁熶竴鍏ュ彛锛氬瓨閲忔墎骞抽」 + 鏂板椤�
+     */
+    public Sms getSms() {
+        this.sms.setXhsms(buildXhsms());
+        this.sms.setMt(buildMt());
+        this.sms.setAliyun(buildAliyun());
+        return this.sms;
+    }
+
+    public void setSms(Sms sms) {
+        this.sms = sms;
+    }
+
+    /**
+     * 寰俊鍏紬鍙烽厤缃粺涓�鍏ュ彛
+     */
+    public Wechat getWechat() {
+        return this.wechat;
+    }
+
+    public void setWechat(Wechat wechat) {
+        this.wechat = wechat;
+    }
+
+    private XhsmsConfig buildXhsms() {
+        XhsmsConfig xhsms = new XhsmsConfig();
+        xhsms.setPath(root.getXhsmsPath());
+        xhsms.setAccount(root.getXhsmsAccount());
+        xhsms.setPwd(root.getXhsmsPwd());
+        xhsms.setExtno(root.getXhsmsjrm());
+        return xhsms;
+    }
+
+    private MtSmsConfig buildMt() {
+        MtSmsConfig mt = new MtSmsConfig();
+        mt.setAccountName(root.getSmsAccountName());
+        mt.setPassword(root.getSmsPassword());
+        mt.setUrl(root.getSmsUrl());
+        mt.setSourceAddr(root.getSmsSourceAddr());
+        mt.setServiceCode(root.getSmsServiceCode());
+        mt.setAppkey(root.getSmsAppkey());
+        mt.setFlag(root.getSmsFlag());
+        return mt;
+    }
+
+    private AliyunSmsConfig buildAliyun() {
+        AliyunSmsConfig aliyun = new AliyunSmsConfig();
+        aliyun.setAccessKeyId(root.getAccessKeyId());
+        aliyun.setAccessKeySecret(root.getAccessKeySecret());
+        aliyun.setSignName(root.getSignName());
+        return aliyun;
+    }
+
+    /**
+     * 鐭俊閰嶇疆鍒嗙粍
+     */
+    @Data
+    public static class Sms {
+
+        private XhsmsConfig xhsms = new XhsmsConfig();
+
+        private MtSmsConfig mt = new MtSmsConfig();
+
+        private AliyunSmsConfig aliyun = new AliyunSmsConfig();
+
+        private ShiyiSms shiyi = new ShiyiSms();
+
+        private MessagingInsert messagingInsert = new MessagingInsert();
+    }
+
+    /**
+     * 鏉窞甯備竴 HIS 鏈嶅姟骞冲彴鐭俊锛坰hiyi-his 閫氶亾锛�
+     */
+    @Data
+    public static class ShiyiSms {
+
+        /**
+         * HIS RunService 鍦板潃銆�
+         * <p>
+         * TODO 寰呯‘璁わ細鍘熷疄鐜版妸 {@code http://192.178.0.104:7790/MediInfoHis.svc} 纭紪鐮佸湪
+         * {@code ShiyiSmsUtil.invokeRunService} 閲岋紝杩欓噷鎻愪负鍙厤缃紝榛樿鍊间笌鍘熺‖缂栫爜淇濇寔涓�鑷淬��
+         */
+        private String wsUrl = "http://192.178.0.104:7790/MediInfoHis.svc";
+
+        /**
+         * 榛樿鎿嶄綔鍛樹唬鐮�
+         */
+        private String defaultCaozuoydm;
+
+        /**
+         * 榛樿鎿嶄綔鍛樺鍚�
+         */
+        private String defaultCaozuoyxm;
+
+        /**
+         * 鐭俊绛惧悕鍓嶇紑锛堝綋鍓嶆湭浣跨敤锛岀暀缁欏悗缁渶瑕佹椂锛�
+         */
+        private String sign = "";
+    }
+
+    /**
+     * 棰勭害鎸傚彿鐭俊骞冲彴锛圡essagingInsert锛孉xis SOAP12锛�
+     */
+    @Data
+    public static class MessagingInsert {
+
+        /**
+         * SOAP 鏈嶅姟鍦板潃銆�
+         * <p>
+         * TODO 寰呯‘璁わ細鍘熷疄鐜版妸 {@code http://218.108.11.29:8081/MessagingInsert.asmx} 纭紪鐮佸湪
+         * {@code MessagingInsertLocator} 鐢熸垚鐨勪唬鐮侀噷锛岃繖閲屾彁涓哄彲閰嶇疆锛岄粯璁ゅ�间笌鍘熺‖缂栫爜涓�鑷淬��
+         */
+        private String wsUrl = "http://218.108.11.29:8081/MessagingInsert.asmx";
+    }
+
+    /**
+     * 寰俊鍏紬鍙风浉鍏抽厤缃�
+     */
+    @Data
+    public static class Wechat {
+
+        private ShiyiWechat shiyi = new ShiyiWechat();
+
+        private Xinhua xinhua = new Xinhua();
+    }
+
+    /**
+     * 甯備竴寰俊鍏紬鍙凤紙hzszlyy 閫氶亾锛�
+     */
+    @Data
+    public static class ShiyiWechat {
+
+        /**
+         * 鎺ュ彛鍦板潃銆�
+         * <p>
+         * TODO 寰呯‘璁わ細鍘� {@code smsUtils.sendChat} 鎶� {@code http://192.200.54.14:5003/sfjk/SendMessage}
+         * 纭紪鐮佸湪鏂规硶閲岋紝杩欓噷鎻愪负鍙厤缃紝榛樿鍊间笌鍘熺‖缂栫爜淇濇寔涓�鑷淬��
+         */
+        private String url = "http://192.200.54.14:5003/sfjk/SendMessage";
+
+        /**
+         * 鎺ュ彛瀵嗛挜銆�
+         * <p>
+         * TODO 寰呯‘璁わ細鍘� {@code smsUtils.sendChat} 鎶� key
+         * {@code ff76f8904f5f32b5ee1739e8ea46e60g} 纭紪鐮佸湪鏂规硶閲岋紝姝ゅ�肩枒浼间负鍗犱綅/娴嬭瘯瀵嗛挜锛岃涓氬姟纭鍚庢浛鎹€��
+         */
+        private String key = "ff76f8904f5f32b5ee1739e8ea46e60g";
+
+        /**
+         * 娑堟伅鏍囬銆�
+         * <p>
+         * TODO 寰呯‘璁わ細鍘熷疄鐜版妸銆屾偍濂斤紝閭�璇锋偍濉啓鍑洪櫌璋冩煡琛紝璇风偣鍑诲~鍐欍�傘�嶅啓姝诲湪 URL 閲岋紝
+         * 鎵�鏈夊閮ㄩ摼鎺ワ紙闅忚/闂嵎/瀹f暀锛夐兘鐢ㄥ悓涓�鍙ユ枃妗堬紝杩欓噷鎻愪负鍙厤缃紝榛樿鍊间笌鍘熸枃妗堜竴鑷淬��
+         */
+        private String title = "鎮ㄥソ锛岄個璇锋偍濉啓鍑洪櫌璋冩煡琛紝璇风偣鍑诲~鍐欍��";
+
+        /**
+         * 娑堟伅鍐呭鍗犱綅銆�
+         * <p>
+         * TODO 寰呯‘璁わ細鍘熷疄鐜板啓姝讳负銆屽緟闅忚銆嶏紝姝ゅ榛樿鍊间笌鍘熷�间竴鑷淬��
+         */
+        private String content = "寰呴殢璁�";
+    }
+
+    /**
+     * 鏂板崕寰俊鍏紬鍙凤紙xh 閫氶亾锛�
+     */
+    @Data
+    public static class Xinhua {
+
+        /**
+         * 鎺ュ彛鏈嶅姟鍚嶏紝鍥哄畾鍊笺��
+         * <p>
+         * 鍘� {@code XinHuaWXReq.service} 榛樿 {@code smarthos.pat.notice}
+         */
+        private String service = "smarthos.pat.notice";
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/config/MtSmsConfig.java b/ruoyi-message/src/main/java/com/ruoyi/message/config/MtSmsConfig.java
new file mode 100644
index 0000000..de9c35c
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/config/MtSmsConfig.java
@@ -0,0 +1,48 @@
+package com.ruoyi.message.config;
+
+import lombok.Data;
+
+/**
+ * 鍗楀崕闄勪竴銆岃涓氭眹鑱氬钩鍙� MT 娑堟伅銆嶉厤缃紙nhfy 閫氶亾锛夈��
+ * <p>
+ * 鐢� {@link MessageProperties#getSms()} 浠� {@link RootMessageProperties} 鐨勬墎骞冲瓧娈电粍瑁呰�屾潵锛�
+ * 瀛楁涓� yml key 鐨勫搴斿叧绯昏鍚勫瓧娈垫敞閲娿��
+ */
+@Data
+public class MtSmsConfig {
+
+    /**
+     * 瀵瑰簲 yml key {@code sms_accountName}
+     */
+    private String accountName;
+
+    /**
+     * 瀵瑰簲 yml key {@code sms_password}
+     */
+    private String password;
+
+    /**
+     * 瀵瑰簲 yml key {@code sms_url}
+     */
+    private String url;
+
+    /**
+     * 瀵瑰簲 yml key {@code sms_sourceAddr}
+     */
+    private String sourceAddr;
+
+    /**
+     * 瀵瑰簲 yml key {@code sms_serviceCode}
+     */
+    private String serviceCode;
+
+    /**
+     * 瀵瑰簲 yml key {@code sms_appkey}
+     */
+    private String appkey;
+
+    /**
+     * 鐭俊绛惧悕鍓嶇紑锛屽搴� yml key {@code sms_flag}
+     */
+    private String flag;
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/config/RootMessageProperties.java b/ruoyi-message/src/main/java/com/ruoyi/message/config/RootMessageProperties.java
new file mode 100644
index 0000000..97ff3c8
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/config/RootMessageProperties.java
@@ -0,0 +1,187 @@
+package com.ruoyi.message.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 瀛橀噺閰嶇疆锛堝瓧娈靛悕涓庡悇绔欑偣 {@code application-<profile>.yml} 鐨� key <b>瀹屽叏鍚屽悕</b>锛夈��
+ * <p>
+ * 鈿狅笍 涓轰粈涔堝繀椤诲悓鍚嶃�佸繀椤绘墎骞筹細
+ * <pre>
+ * Spring Boot 鐨勬澗鏁g粦瀹氭槸鎸夈�岀偣鍒嗚矾寰� + 閫愭瑙勮寖鍖栧悗缂�鍖归厤銆嶅伐浣滅殑銆�
+ * 涓�涓彨 {@code xhsmsPath} 鐨� key锛屽彧鑳界粦瀹氬埌銆屽瓧娈佃矾寰勪负 xhsmsPath銆嶇殑浣嶇疆锛�
+ * 瀹�<b>涓嶅彲鑳�</b>钀藉埌 {@code sms.xhsms.path} 涓娾�斺�斿嵆浣� {@code xhsms} 鏄� {@code sms} 鐨勫瓙瀛楁銆�
+ * {@code path} 鏄� {@code xhsms} 鐨勫瓙瀛楁涔熶笉琛岋紙瀹炴祴宸茬‘璁わ細宓屽缁戝畾鎭掍负 null锛夈��
+ * </pre>
+ * 鎵�浠ユ湰绫诲埢鎰忎繚鎸佹墎骞筹紝瀛楁鍚� = yml key锛�
+ * <ul>
+ *   <li>{@code xhsmsPath} / {@code xhsmsAccount} / {@code xhsmsPwd} / {@code xhsmsjrm}</li>
+ *   <li>{@code sms_accountName} / {@code sms_password} / {@code sms_url} / {@code sms_sourceAddr}
+ *       / {@code sms_serviceCode} / {@code sms_appkey} / {@code sms_flag}</li>
+ *   <li>{@code accessKeyId} / {@code accessKeySecret} / {@code signName}</li>
+ * </ul>
+ * 闇�瑕佸垎缁勮涔夋椂鐢� {@link MessageProperties} 璐熻矗杞崲锛屼笟鍔′唬鐮佷笉鐩存帴渚濊禆瀛楁甯冨眬銆�
+ * <p>
+ * 鍚勭珯鐐� yml 涓�寰嬩笉闇�瑕佹敼鍔ㄣ��
+ */
+@Component
+@ConfigurationProperties
+public class RootMessageProperties {
+
+    // ------------------------------------------------------------------ 鏂板崕鐭俊缃戝叧
+    /** 瀵瑰簲 {@code xhsmsPath} */
+    private String xhsmsPath;
+
+    /** 瀵瑰簲 {@code xhsmsAccount} */
+    private String xhsmsAccount;
+
+    /** 瀵瑰簲 {@code xhsmsPwd} */
+    private String xhsmsPwd;
+
+    /** 瀵瑰簲 {@code xhsmsjrm}锛堣櫄鎷熸帴鍏ョ爜锛� */
+    private String xhsmsjrm;
+
+    // ------------------------------------------------------------------ 鍗楀崕闄勪竴 MT
+    /** 瀵瑰簲 {@code sms_accountName} */
+    private String smsAccountName;
+
+    /** 瀵瑰簲 {@code sms_password} */
+    private String smsPassword;
+
+    /** 瀵瑰簲 {@code sms_url} */
+    private String smsUrl;
+
+    /** 瀵瑰簲 {@code sms_sourceAddr} */
+    private String smsSourceAddr;
+
+    /** 瀵瑰簲 {@code sms_serviceCode} */
+    private String smsServiceCode;
+
+    /** 瀵瑰簲 {@code sms_appkey} */
+    private String smsAppkey;
+
+    /** 瀵瑰簲 {@code sms_flag}锛堢煭淇$鍚嶅墠缂�锛� */
+    private String smsFlag;
+
+    // ------------------------------------------------------------------ 闃块噷浜戠煭淇�
+    /** 瀵瑰簲 {@code accessKeyId} */
+    private String accessKeyId;
+
+    /** 瀵瑰簲 {@code accessKeySecret} */
+    private String accessKeySecret;
+
+    /** 瀵瑰簲 {@code signName} */
+    private String signName;
+
+    public String getXhsmsPath() {
+        return xhsmsPath;
+    }
+
+    public void setXhsmsPath(String xhsmsPath) {
+        this.xhsmsPath = xhsmsPath;
+    }
+
+    public String getXhsmsAccount() {
+        return xhsmsAccount;
+    }
+
+    public void setXhsmsAccount(String xhsmsAccount) {
+        this.xhsmsAccount = xhsmsAccount;
+    }
+
+    public String getXhsmsPwd() {
+        return xhsmsPwd;
+    }
+
+    public void setXhsmsPwd(String xhsmsPwd) {
+        this.xhsmsPwd = xhsmsPwd;
+    }
+
+    public String getXhsmsjrm() {
+        return xhsmsjrm;
+    }
+
+    public void setXhsmsjrm(String xhsmsjrm) {
+        this.xhsmsjrm = xhsmsjrm;
+    }
+
+    public String getSmsAccountName() {
+        return smsAccountName;
+    }
+
+    public void setSmsAccountName(String smsAccountName) {
+        this.smsAccountName = smsAccountName;
+    }
+
+    public String getSmsPassword() {
+        return smsPassword;
+    }
+
+    public void setSmsPassword(String smsPassword) {
+        this.smsPassword = smsPassword;
+    }
+
+    public String getSmsUrl() {
+        return smsUrl;
+    }
+
+    public void setSmsUrl(String smsUrl) {
+        this.smsUrl = smsUrl;
+    }
+
+    public String getSmsSourceAddr() {
+        return smsSourceAddr;
+    }
+
+    public void setSmsSourceAddr(String smsSourceAddr) {
+        this.smsSourceAddr = smsSourceAddr;
+    }
+
+    public String getSmsServiceCode() {
+        return smsServiceCode;
+    }
+
+    public void setSmsServiceCode(String smsServiceCode) {
+        this.smsServiceCode = smsServiceCode;
+    }
+
+    public String getSmsAppkey() {
+        return smsAppkey;
+    }
+
+    public void setSmsAppkey(String smsAppkey) {
+        this.smsAppkey = smsAppkey;
+    }
+
+    public String getSmsFlag() {
+        return smsFlag;
+    }
+
+    public void setSmsFlag(String smsFlag) {
+        this.smsFlag = smsFlag;
+    }
+
+    public String getAccessKeyId() {
+        return accessKeyId;
+    }
+
+    public void setAccessKeyId(String accessKeyId) {
+        this.accessKeyId = accessKeyId;
+    }
+
+    public String getAccessKeySecret() {
+        return accessKeySecret;
+    }
+
+    public void setAccessKeySecret(String accessKeySecret) {
+        this.accessKeySecret = accessKeySecret;
+    }
+
+    public String getSignName() {
+        return signName;
+    }
+
+    public void setSignName(String signName) {
+        this.signName = signName;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/config/XhsmsConfig.java b/ruoyi-message/src/main/java/com/ruoyi/message/config/XhsmsConfig.java
new file mode 100644
index 0000000..f5aef9d
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/config/XhsmsConfig.java
@@ -0,0 +1,33 @@
+package com.ruoyi.message.config;
+
+import lombok.Data;
+
+/**
+ * 鏂板崕鐭俊缃戝叧閰嶇疆锛坸h 閫氶亾锛屽競涓� hzszlyy 閫氶亾澶嶇敤鍚屼竴濂楀湴鍧�/璐﹀彿锛夈��
+ * <p>
+ * 鐢� {@link MessageProperties#getSms()} 浠� {@link RootMessageProperties} 鐨勬墎骞冲瓧娈电粍瑁呰�屾潵锛�
+ * 瀛楁涓� yml key 鐨勫搴斿叧绯伙細{@code xhsmsPath} / {@code xhsmsAccount} / {@code xhsmsPwd} / {@code xhsmsjrm}銆�
+ */
+@Data
+public class XhsmsConfig {
+
+    /**
+     * 缃戝叧鍦板潃锛屽搴� yml key {@code xhsmsPath}
+     */
+    private String path;
+
+    /**
+     * 璐﹀彿锛屽搴� yml key {@code xhsmsAccount}
+     */
+    private String account;
+
+    /**
+     * 瀵嗙爜锛屽搴� yml key {@code xhsmsPwd}
+     */
+    private String pwd;
+
+    /**
+     * 铏氭嫙鎺ュ叆鐮侊紝瀵瑰簲 yml key {@code xhsmsjrm}
+     */
+    private String extno;
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/AbstractSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/AbstractSmsSender.java
new file mode 100644
index 0000000..b003656
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/AbstractSmsSender.java
@@ -0,0 +1,40 @@
+package com.ruoyi.message.sms;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 鐭俊鍙戦�佹柟鍏叡鍩虹被锛氱粺涓�鏃ュ織銆佸弬鏁版牎楠屻�佸紓甯稿厹搴曘��
+ */
+public abstract class AbstractSmsSender implements SmsSender {
+
+    @Override
+    public SendResult send(SmsSendRequest request) {
+        if (request == null || StringUtils.isBlank(request.getPhone())) {
+            return SendResult.fail(key(), MessageChannel.SMS, "鎵嬫満鍙蜂负绌�", null);
+        }
+        if (StringUtils.isBlank(request.getContent())) {
+            return SendResult.fail(key(), MessageChannel.SMS, "鐭俊鍐呭涓虹┖", null);
+        }
+        try {
+            return doSend(request);
+        } catch (Exception e) {
+            logError(request, e);
+            return SendResult.fail(key(), MessageChannel.SMS, "鐭俊鍙戦�佸紓甯革細" + e.getMessage(), null);
+        }
+    }
+
+    /**
+     * 鐪熸鐨勫彂閫侀�昏緫锛岀敱鍚勬笭閬撳疄鐜�
+     */
+    protected abstract SendResult doSend(SmsSendRequest request) throws Exception;
+
+    /**
+     * 寮傚父鏃ュ織锛屽瓙绫诲彲瑕嗗啓琛ュ厖涓婁笅鏂�
+     */
+    protected void logError(SmsSendRequest request, Exception e) {
+        org.slf4j.LoggerFactory.getLogger(getClass())
+                .error("銆恵}銆戠煭淇″彂閫佸紓甯革紝鎵嬫満鍙凤細{}锛岄敊璇細{}", key(), request.getPhone(), e.getMessage(), e);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSendRequest.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSendRequest.java
new file mode 100644
index 0000000..064c012
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSendRequest.java
@@ -0,0 +1,86 @@
+package com.ruoyi.message.sms;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 鐭俊鍙戦�佽姹傦紙涓庡叿浣撳彂閫佹柟鏃犲叧鐨勭粺涓�鍏ュ弬锛夈��
+ * <p>
+ * 鍚勫彂閫佹柟闇�瑕佺殑宸紓鍙傛暟锛堜附姘寸殑鏈烘瀯閰嶇疆銆佸競涓�鐨勯櫌鍖恒�佹柊鍗庣殑妯℃澘绛夛級閫氳繃
+ * {@link #extras} 閫忎紶锛岄伩鍏嶄负浜嗗皯鏁扮珯鐐规薄鏌撳叕鍏辨帴鍙c��
+ */
+@Data
+public class SmsSendRequest implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎵嬫満鍙凤紙澶氫釜鐢ㄨ嫳鏂囬�楀彿鍒嗛殧锛屽 13500000001,13500000002锛�
+     */
+    private String phone;
+
+    /**
+     * 鐭俊鍐呭锛堣皟鐢ㄦ柟宸叉嫾鎺ュソ绛惧悕/妯℃澘鍙橀噺锛�
+     */
+    private String content;
+
+    /**
+     * 鏈烘瀯ID锛岄儴鍒嗗彂閫佹柟锛堜附姘达級鎸夋満鏋勬煡閰嶇疆
+     */
+    private String orgid;
+
+    /**
+     * 闄㈠尯鏍囪瘑锛屽競涓�鍖哄垎婀栨花/鍚村北涓ゅ绛惧悕锛�
+     * 1=婀栨花锛堛�愭澀宸炲競绗竴浜烘皯鍖婚櫌銆戯級锛屽叾浠�/绌�=鍚村北锛堛�愭澀宸炲競鑲跨槫鍖婚櫌銆戯級
+     */
+    private String campus;
+
+    /**
+     * 鐭俊妯℃澘缂栫爜锛堥樋閲屼簯绛夋ā鏉垮寲鍙戦�佹柟浣跨敤锛�
+     */
+    private String templateCode;
+
+    /**
+     * 妯℃澘鍙傛暟 JSON锛堥樋閲屼簯绛夋ā鏉垮寲鍙戦�佹柟浣跨敤锛�
+     */
+    private String templateParam;
+
+    /**
+     * 鎵╁睍鍙傛暟
+     */
+    private Map<String, Object> extras;
+
+    public static SmsSendRequest of(String phone, String content) {
+        SmsSendRequest request = new SmsSendRequest();
+        request.setPhone(phone);
+        request.setContent(content);
+        return request;
+    }
+
+    public static SmsSendRequest of(String phone, String content, String orgid) {
+        SmsSendRequest request = of(phone, content);
+        request.setOrgid(orgid);
+        return request;
+    }
+
+    /**
+     * 杩藉姞涓�涓墿灞曞弬鏁�
+     */
+    public SmsSendRequest putExtra(String key, Object value) {
+        if (this.extras == null) {
+            this.extras = new LinkedHashMap<>();
+        }
+        this.extras.put(key, value);
+        return this;
+    }
+
+    /**
+     * 璇诲彇鎵╁睍鍙傛暟
+     */
+    public Object getExtra(String key) {
+        return this.extras == null ? null : this.extras.get(key);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSender.java
new file mode 100644
index 0000000..65fed48
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSender.java
@@ -0,0 +1,35 @@
+package com.ruoyi.message.sms;
+
+import com.ruoyi.message.SendResult;
+
+/**
+ * 鐭俊鍙戦�佹柟锛堜竴涓笭閬撲竴涓疄鐜帮級銆�
+ * <p>
+ * 鍚勭珯鐐瑰鎺ユ柟寮忓樊寮傚緢澶� 鈥斺�� 鎶ユ枃鏍煎紡銆侀壌鏉�/绛惧悕銆乼oken 鎹㈠彇銆佽繑鍥炵爜鍒ゅ畾銆侀厤缃潵婧愰兘涓嶅悓锛�
+ * 鍥犳涓嶈鐢ㄤ竴涓疄鐜板姞鍙傛暟鍒嗘敮鏉ュ仛锛岃�屾槸涓�涓笭閬撲竴涓被锛岀被鍐呴儴淇濇寔涓庣嚎涓婂畬鍏ㄤ竴鑷寸殑琛屼负銆�
+ */
+public interface SmsSender {
+
+    /**
+     * 鍙戦�佹柟鍞竴 key銆�
+     * <p>
+     * 璇� key 鍚屾椂鏄� {@code spring.profiles.active} 鐨勫彇鍊硷紙xh / ls / sltd / nhfy / hzszlyy ...锛夛紝
+     * 鐢� {@code MessageSenderFactory} 鎸� key 璺敱銆�
+     */
+    String key();
+
+    /**
+     * 鍙戦�佺煭淇�
+     *
+     * @param request 缁熶竴鍏ュ弬
+     * @return 缁熶竴缁撴灉锛屼笉鎶涘紓甯革紙缃戠粶/瑙f瀽寮傚父涔熶細琚寘瑁呮垚澶辫触缁撴灉锛�
+     */
+    SendResult send(SmsSendRequest request);
+
+    /**
+     * 鍙戦�佹柟璇存槑锛岀敤浜庢棩蹇椾笌鎺掓煡
+     */
+    default String description() {
+        return key();
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSenderFactory.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSenderFactory.java
new file mode 100644
index 0000000..2c1d34f
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/SmsSenderFactory.java
@@ -0,0 +1,108 @@
+package com.ruoyi.message.sms;
+
+import com.ruoyi.message.SendException;
+import com.ruoyi.message.SendResult;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * 鐭俊鍙戦�佹柟宸ュ巶锛氭寜 key 璺敱鍒颁竴涓叿浣撳疄鐜帮紝璋冪敤鏂逛笉鍐嶉渶瑕� {@code if (active.equals("xx"))} 纭垎鏀��
+ * <p>
+ * Spring 浼氳嚜鍔ㄦ妸鎵�鏈� {@link SmsSender} 娉ㄥ叆杩涙潵锛屾柊澧炰竴涓珯鐐瑰彧闇�鏂板涓�涓疄鐜扮被銆�
+ */
+@Slf4j
+@Component
+public class SmsSenderFactory {
+
+    /**
+     * 绔欑偣 profile 鈫� 鐭俊閫氶亾 key 鐨勬槧灏勩��
+     * <p>
+     * 鐩墠涓よ竟鍙栧�煎畬鍏ㄤ竴鑷达紙{@code spring.profiles.active} 鐩存帴灏辨槸娓犻亾鍚嶏級锛�
+     * 鍗曠嫭鐣欏嚭鏄犲皠琛ㄦ槸涓轰簡灏嗘潵 profile 鍚嶄笌娓犻亾鍚嶈В鑰︽椂涓嶆敼璋冪敤鏂广��
+     */
+    private static final Map<String, String> PROFILE_ALIAS = new LinkedHashMap<>();
+
+    static {
+        PROFILE_ALIAS.put("xh", "xh");
+        PROFILE_ALIAS.put("ls", "ls");
+        PROFILE_ALIAS.put("sltd", "sltd");
+        PROFILE_ALIAS.put("nhfy", "nhfy");
+        PROFILE_ALIAS.put("hzszlyy", "hzszlyy");
+    }
+
+    private final Map<String, SmsSender> senders = new LinkedHashMap<>();
+
+    public SmsSenderFactory(List<SmsSender> senderList) {
+        for (SmsSender sender : senderList) {
+            SmsSender exists = senders.put(sender.key(), sender);
+            if (exists != null) {
+                throw new IllegalStateException("鐭俊鍙戦�佹柟 key 閲嶅锛�" + sender.key()
+                        + "锛屽啿绐佸疄鐜帮細" + exists.getClass().getName() + " 涓� " + sender.getClass().getName());
+            }
+        }
+        log.info("銆怱msSenderFactory銆戝凡娉ㄥ唽鐭俊鍙戦�佹柟锛歿}", senders.keySet());
+    }
+
+    /**
+     * 鎸� key 鑾峰彇鍙戦�佹柟
+     *
+     * @param key 娓犻亾 key锛堝嵆 {@code spring.profiles.active} 鍙栧�硷級
+     * @return 鍙戦�佹柟瀹炵幇
+     * @throws SendException 鎵句笉鍒板搴斿疄鐜版椂鎶涘嚭
+     */
+    public SmsSender get(String key) {
+        String resolved = resolveSmsKey(key);
+        SmsSender sender = resolved == null ? null : senders.get(resolved);
+        if (sender == null) {
+            throw new SendException("鏈壘鍒扮煭淇″彂閫佹柟锛宬ey=" + key + "锛屽凡娉ㄥ唽锛�" + senders.keySet());
+        }
+        return sender;
+    }
+
+    /**
+     * 鎸� key 鑾峰彇鍙戦�佹柟锛屾壘涓嶅埌杩斿洖 {@code null}
+     */
+    public SmsSender getOrNull(String key) {
+        String resolved = resolveSmsKey(key);
+        return resolved == null ? null : senders.get(resolved);
+    }
+
+    /**
+     * 鎸� key 鍙戦�佺煭淇★紙绛変环浜庢棫浠g爜閲岄偅 200 琛� if-else 鐨勭粨鏋滐級
+     */
+    public SendResult send(String key, SmsSendRequest request) {
+        return get(key).send(request);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁瀛樺湪璇� key 鐨勫彂閫佹柟
+     */
+    public boolean supports(String key) {
+        return getOrNull(key) != null;
+    }
+
+    /**
+     * 宸叉敞鍐岀殑娓犻亾 key
+     */
+    public Set<String> keys() {
+        return new TreeSet<>(senders.keySet());
+    }
+
+    /**
+     * 绔欑偣 profile 鈫� 娓犻亾 key
+     */
+    public static String resolveSmsKey(String profile) {
+        if (StringUtils.isEmpty(profile)) {
+            return null;
+        }
+        String alias = PROFILE_ALIAS.get(profile);
+        return alias == null ? profile : alias;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.java
new file mode 100644
index 0000000..5e9cbdd
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.java
@@ -0,0 +1,204 @@
+package com.ruoyi.message.sms.provider.aliyun;
+
+import com.aliyun.dysmsapi20170525.Client;
+import com.aliyun.dysmsapi20170525.models.AddSmsTemplateRequest;
+import com.aliyun.dysmsapi20170525.models.AddSmsTemplateResponse;
+import com.aliyun.dysmsapi20170525.models.AddSmsTemplateResponseBody;
+import com.aliyun.dysmsapi20170525.models.ModifySmsTemplateRequest;
+import com.aliyun.dysmsapi20170525.models.ModifySmsTemplateResponse;
+import com.aliyun.dysmsapi20170525.models.ModifySmsTemplateResponseBody;
+import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateListRequest;
+import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateListResponse;
+import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateListResponseBody;
+import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateRequest;
+import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateResponse;
+import com.aliyun.dysmsapi20170525.models.QuerySmsTemplateResponseBody;
+import com.aliyun.dysmsapi20170525.models.SendBatchSmsRequest;
+import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponse;
+import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponseBody;
+import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
+import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
+import com.aliyun.tea.TeaException;
+import com.aliyun.teaopenapi.models.Config;
+import com.aliyun.teautil.Common;
+import com.aliyun.teautil.models.RuntimeOptions;
+import com.ruoyi.message.config.MessageProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 闃块噷浜戠煭淇� API銆�
+ * <p>
+ * 杩佺Щ璇存槑锛氶�昏緫鍙栬嚜 {@code com.smartor.service.impl.BaseSmsaccountServiceImpl}锛�
+ * 浣�<b>涓嶅啀渚濊禆 smartor 鐨� domain 瀵硅薄</b>锛坽@code BaseSmsRequest} / {@code BatchBaseSmsRequest} /
+ * {@code TemplateSmsRequest}锛夛紝鏀逛负鐩存帴鎺ユ敹鍩虹鍙傛暟锛屼粠鑰岃鏈ā鍧楀彲浠ユ斁鍦�
+ * {@code ruoyi-system} 涔嬪墠銆佽鎵�鏈変笟鍔℃ā鍧楀鐢ㄣ��
+ * <p>
+ * 鍘� {@code BaseSmsaccountServiceImpl} 淇濈暀涓恒�岀煭淇¤处鍙风鐞� + DB 璇诲啓銆嶇殑 Service锛�
+ * 鍏朵笂鐨勯樋閲屼簯璋冪敤鏀逛负濮旀墭鏈被锛堣鏀归�犺鏄庯級銆�
+ */
+@Slf4j
+@Component
+public class AliYunSmsApi {
+
+    private final MessageProperties properties;
+
+    public AliYunSmsApi(MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * 鍙戦�佺煭淇�
+     *
+     * @param phoneNumbers  鎵嬫満鍙凤紝澶氫釜鐢ㄩ�楀彿鍒嗛殧
+     * @param templateCode  妯℃澘缂栫爜
+     * @param templateParam 妯℃澘鍙傛暟 JSON
+     */
+    public SendSmsResponseBody sendSms(String phoneNumbers, String templateCode, String templateParam) {
+        try {
+            Client client = createClient();
+            SendSmsRequest sendSmsRequest = new SendSmsRequest()
+                    .setPhoneNumbers(phoneNumbers)
+                    .setSignName(properties.getSms().getAliyun().getSignName())
+                    .setTemplateCode(templateCode)
+                    .setTemplateParam(templateParam);
+            SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, new RuntimeOptions());
+            return sendSmsResponse.getBody();
+        } catch (Exception e) {
+            log.error("闃块噷浜戠煭淇″彂閫佸け璐ワ紝phoneNumbers锛歿}锛宼emplateCode锛歿}", phoneNumbers, templateCode, e);
+        }
+        return null;
+    }
+
+    /**
+     * 鎵归噺鍙戦�佺煭淇�
+     */
+    public SendBatchSmsResponseBody batchSendMsg(List<String> phoneNumbers, String templateCode) {
+        try {
+            Client client = createClient();
+            List<String> signNameJson = new ArrayList<>();
+            for (int i = 0; i < phoneNumbers.size(); i++) {
+                signNameJson.add("\"" + properties.getSms().getAliyun().getSignName() + "\"");
+            }
+            SendBatchSmsRequest sendBatchSmsRequest = new SendBatchSmsRequest()
+                    .setSignNameJson(signNameJson.toString())
+                    .setPhoneNumberJson(phoneNumbers.toString())
+                    .setTemplateCode(templateCode);
+            RuntimeOptions runtime = new RuntimeOptions();
+            try {
+                SendBatchSmsResponse sendBatchSmsResponse = client.sendBatchSmsWithOptions(sendBatchSmsRequest, runtime);
+                return sendBatchSmsResponse.getBody();
+            } catch (TeaException error) {
+                Common.assertAsString(error.message);
+            } catch (Exception innerError) {
+                TeaException error = new TeaException(innerError.getMessage(), innerError);
+                Common.assertAsString(error.message);
+            }
+        } catch (Exception e) {
+            log.error("闃块噷浜戠煭淇℃壒閲忓彂閫佸け璐ワ紝templateCode锛歿}", templateCode, e);
+        }
+        return null;
+    }
+
+    /**
+     * 鏂板鐭俊妯℃澘
+     */
+    public AddSmsTemplateResponseBody addSmsTemplate(Integer templateType, String templateName,
+                                                     String templateContent, String remark) {
+        try {
+            Client client = createClient();
+            AddSmsTemplateRequest addSmsTemplateRequest = new AddSmsTemplateRequest()
+                    .setTemplateType(templateType)
+                    .setTemplateName(templateName)
+                    .setTemplateContent(templateContent)
+                    .setRemark(remark);
+            RuntimeOptions runtime = new RuntimeOptions();
+            AddSmsTemplateResponse response = client.addSmsTemplateWithOptions(addSmsTemplateRequest, runtime);
+            return response.getBody();
+        } catch (TeaException error) {
+            Common.assertAsString(error.message);
+        } catch (Exception innerError) {
+            TeaException error = new TeaException(innerError.getMessage(), innerError);
+            Common.assertAsString(error.message);
+        }
+        return null;
+    }
+
+    /**
+     * 淇敼鐭俊妯℃澘
+     */
+    public ModifySmsTemplateResponseBody modifySmsTemplate(Integer templateType, String templateName,
+                                                          String templateCode, String templateContent, String remark) {
+        try {
+            Client client = createClient();
+            ModifySmsTemplateRequest modifySmsTemplateRequest = new ModifySmsTemplateRequest();
+            modifySmsTemplateRequest.setTemplateType(templateType);
+            modifySmsTemplateRequest.setTemplateName(templateName);
+            modifySmsTemplateRequest.setTemplateCode(templateCode);
+            modifySmsTemplateRequest.setTemplateContent(templateContent);
+            modifySmsTemplateRequest.setRemark(remark);
+            RuntimeOptions runtime = new RuntimeOptions();
+            ModifySmsTemplateResponse response = client.modifySmsTemplateWithOptions(modifySmsTemplateRequest, runtime);
+            return response.getBody();
+        } catch (TeaException error) {
+            Common.assertAsString(error.message);
+        } catch (Exception innerError) {
+            TeaException error = new TeaException(innerError.getMessage(), innerError);
+            Common.assertAsString(error.message);
+        }
+        return null;
+    }
+
+    /**
+     * 鏌ヨ鐭俊妯℃澘鍒楄〃
+     */
+    public QuerySmsTemplateListResponseBody querySmsTemplate(Integer pageIndex, Integer pageSize) {
+        try {
+            Client client = createClient();
+            QuerySmsTemplateListRequest request = new QuerySmsTemplateListRequest()
+                    .setPageIndex(pageIndex)
+                    .setPageSize(pageSize);
+            RuntimeOptions runtime = new RuntimeOptions();
+            QuerySmsTemplateListResponse response = client.querySmsTemplateListWithOptions(request, runtime);
+            return response.getBody();
+        } catch (TeaException error) {
+            Common.assertAsString(error.message);
+        } catch (Exception innerError) {
+            TeaException error = new TeaException(innerError.getMessage(), innerError);
+            Common.assertAsString(error.message);
+        }
+        return null;
+    }
+
+    /**
+     * 鏌ヨ鐭俊妯℃澘瀹℃牳鐘舵��
+     */
+    public QuerySmsTemplateResponseBody querySmsTemplateStatus(String templateCode) {
+        try {
+            Client client = createClient();
+            QuerySmsTemplateRequest request = new QuerySmsTemplateRequest().setTemplateCode(templateCode);
+            RuntimeOptions runtime = new RuntimeOptions();
+            QuerySmsTemplateResponse response = client.querySmsTemplateWithOptions(request, runtime);
+            return response.getBody();
+        } catch (TeaException error) {
+            Common.assertAsString(error.message);
+        } catch (Exception innerError) {
+            TeaException error = new TeaException(innerError.getMessage(), innerError);
+            Common.assertAsString(error.message);
+        }
+        return null;
+    }
+
+    private Client createClient() throws Exception {
+        Config config = new Config()
+                .setAccessKeyId(properties.getSms().getAliyun().getAccessKeyId())
+                .setAccessKeySecret(properties.getSms().getAliyun().getAccessKeySecret());
+        // 璁块棶鐨勫煙鍚�
+        config.endpoint = "dysmsapi.aliyuncs.com";
+        return new Client(config);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.java
new file mode 100644
index 0000000..f0683dc
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.java
@@ -0,0 +1,103 @@
+package com.ruoyi.message.sms.provider.aliyun;
+
+import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 闃块噷浜戠煭淇″彂閫佹柟锛坽@code aliyun} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛氶樋閲屼簯 dysmsapi SDK锛寋@code SignName + TemplateCode + TemplateParam}锛�
+ * 鎴愬姛鍒ゅ畾涓哄搷搴� {@code Code == "OK"}銆�
+ * <p>
+ * 璇存槑锛氳閫氶亾鐩墠鍙湪 {@code BaseSmsaccountServiceImpl}锛堢煭淇¤处鍙�/妯℃澘绠$悊锛夐噷浣跨敤锛�
+ * 涓氬姟鍙戦�佹祦绋嬫湭璧板畠銆傛敹鍙e悗鍙敱宸ュ巶缁熶竴璋冨害銆�
+ */
+@Slf4j
+@Component
+public class AliYunSmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key
+     */
+    public static final String KEY = "aliyun";
+
+    private final AliYunSmsApi aliYunSmsApi;
+
+    public AliYunSmsSender(AliYunSmsApi aliYunSmsApi) {
+        this.aliYunSmsApi = aliYunSmsApi;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "闃块噷浜戠煭淇★紙dysmsapi锛屾ā鏉垮寲锛�";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) {
+        //闃块噷浜戠煭淇′笉璧板唴瀹圭洿鍙戯紝鑰屾槸 妯℃澘缂栫爜 + 妯℃澘鍙傛暟
+        SendSmsRequestAdapter adapter = new SendSmsRequestAdapter(request);
+        if (adapter.templateParam == null) {
+            return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊妯℃澘鍙傛暟涓虹┖", null);
+        }
+
+        SendSmsResponseBody body = aliYunSmsApi.sendSms(
+                adapter.phone, adapter.templateCode, adapter.templateParam);
+        if (body == null) {
+            return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", null);
+        }
+        log.info("銆恵}銆戦樋閲屼簯鐭俊鍙戦�佺粨鏋滐細code={}, message={}", KEY, body.getCode(), body.getMessage());
+        if ("OK".equals(body.getCode())) {
+            return SendResult.success(KEY, MessageChannel.SMS, body.getMessage())
+                    .withCode(body.getCode())
+                    .withMessage(body.getBizId());
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, body.getMessage(), body.getMessage())
+                .withCode(body.getCode());
+    }
+
+    /**
+     * 缁曡繃鍩虹被銆屽唴瀹逛笉鑳戒负绌恒�嶇殑鏍¢獙锛氶樋閲屼簯鐢ㄦā鏉垮弬鏁帮紝涓嶇敤 content 鐩村彂銆�
+     */
+    @Override
+    public SendResult send(SmsSendRequest request) {
+        if (request == null || request.getPhone() == null || request.getPhone().trim().isEmpty()) {
+            return SendResult.fail(KEY, MessageChannel.SMS, "鎵嬫満鍙蜂负绌�", null);
+        }
+        try {
+            return doSend(request);
+        } catch (Exception e) {
+            log.error("銆恵}銆戦樋閲屼簯鐭俊鍙戦�佸紓甯革細{}", KEY, e.getMessage(), e);
+            return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸紓甯革細" + e.getMessage(), null);
+        }
+    }
+
+    /**
+     * 灏忛�傞厤鍣細鎶婄粺涓�鍏ュ弬鏄犲皠鎴愰樋閲屼簯闇�瑕佺殑涓変釜瀛楁銆�
+     * <p>
+     * 鍏煎鏃ц皟鐢ㄦ柟锛坽@code BaseSmsRequest}锛変紶鍙備範鎯細鎵嬫満鍙疯蛋 {@code phone}锛�
+     * 妯℃澘缂栫爜/鍙傛暟璧� {@code templateCode} / {@code templateParam}銆�
+     */
+    private static final class SendSmsRequestAdapter {
+        private final String phone;
+        private final String templateCode;
+        private final String templateParam;
+
+        private SendSmsRequestAdapter(SmsSendRequest request) {
+            this.phone = request.getPhone();
+            this.templateCode = request.getTemplateCode();
+            this.templateParam = request.getTemplateParam() != null
+                    ? request.getTemplateParam()
+                    : request.getContent();
+        }
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.java
new file mode 100644
index 0000000..467de6a
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.java
@@ -0,0 +1,82 @@
+package com.ruoyi.message.sms.provider.hzszlyy;
+
+import com.ruoyi.common.utils.HttpUtil;
+import com.ruoyi.common.utils.sign.Md5Utils;
+import com.ruoyi.message.config.MessageProperties;
+import com.ruoyi.message.config.XhsmsConfig;
+import com.ruoyi.message.config.RootMessageProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * 鏉窞甯備竴鐭俊缃戝叧 API锛堟柊鍗庣綉鍏冲湴鍧� + 甯備竴鑷湁绛惧悕绠楁硶锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛欽SON 鎶ユ枃 {@code userName/content/phoneList/timestamp/sign}锛�
+ * 绛惧悕涓� {@code MD5(userName + timestamp + MD5(passWord))}銆�
+ * <p>
+ * 鈿狅笍 绔欑偣宸紓锛堝繀椤诲尯鍒嗭紝涓嶈兘鍚堝苟锛夛細
+ * <ul>
+ *   <li>鍚村北闄㈠尯锛氱鍚嶅墠缂� {@code 銆愭澀宸炲競鑲跨槫鍖婚櫌銆憓锛�</li>
+ *   <li>婀栨花闄㈠尯锛氱鍚嶅墠缂� {@code 銆愭澀宸炲競绗竴浜烘皯鍖婚櫌銆憓銆�</li>
+ * </ul>
+ * 鍘熷疄鐜板垎涓や釜鏂规硶 {@code smsUtils.sendSms} / {@code smsUtils.sendSms1} 鎵胯浇杩欎竴宸紓銆�
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.ruoyi.common.utils.sms.smsUtils}锛岀鍚嶅墠缂�淇濇寔涓嶅彉銆�
+ */
+@Slf4j
+@Component
+public class ShiyiSmsApi {
+
+    /**
+     * 鍚村北闄㈠尯鐭俊绛惧悕鍓嶇紑
+     */
+    public static final String PREFIX_WUSHAN = "銆愭澀宸炲競鑲跨槫鍖婚櫌銆�";
+
+    /**
+     * 婀栨花闄㈠尯鐭俊绛惧悕鍓嶇紑
+     */
+    public static final String PREFIX_HIBIN = "銆愭澀宸炲競绗竴浜烘皯鍖婚櫌銆�";
+
+    private final MessageProperties properties;
+
+    public ShiyiSmsApi(MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * 鍚村北闄㈠尯鍙戦�侊紙绛変环 {@code smsUtils.sendSms}锛�
+     *
+     * @return 缃戝叧杩斿洖鐨勫瓧绗︿覆锛屽惈銆屽鐞嗘垚鍔熴�嶈〃绀烘垚鍔�
+     */
+    public String sendWushan(String phone, String content) {
+        return send(phone, content, PREFIX_WUSHAN);
+    }
+
+    /**
+     * 婀栨花闄㈠尯鍙戦�侊紙绛変环 {@code smsUtils.sendSms1}锛�
+     *
+     * @return 缃戝叧杩斿洖鐨勫瓧绗︿覆锛屽惈銆屽鐞嗘垚鍔熴�嶈〃绀烘垚鍔�
+     */
+    public String sendHibin(String phone, String content) {
+        return send(phone, content, PREFIX_HIBIN);
+    }
+
+    private String send(String phone, String content, String prefix) {
+        XhsmsConfig cfg = properties.getSms().getXhsms();
+        long timestamp = new Date().getTime();
+        String sign = Md5Utils.hash(cfg.getAccount() + timestamp + Md5Utils.hash(cfg.getPwd()));
+        String fullContent = prefix + content;
+        String jsonMsg = "{"
+                + "\"userName\": \"" + cfg.getAccount() + "\","
+                + "\"content\": \"" + fullContent + "\","
+                + "\"phoneList\": [" + phone + "],"
+                + "\"timestamp\": " + timestamp + ","
+                + "\"sign\": \"" + sign + "\""
+                + "}";
+        log.info("銆怱hiyiSmsApi銆戝競涓�鐭俊鍙戦�侊紝鍦板潃锛歿}锛岀鍚嶅墠缂�锛歿}锛屾墜鏈哄彿锛歿}", cfg.getPath(), prefix, phone);
+        Boolean sendMsg = HttpUtil.postJsonRequest(cfg.getPath(), jsonMsg);
+        return String.valueOf(sendMsg);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.java
new file mode 100644
index 0000000..12d8127
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.java
@@ -0,0 +1,68 @@
+package com.ruoyi.message.sms.provider.hzszlyy;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鏉窞甯備竴鐭俊鍙戦�佹柟锛坽@code hzszlyy} 閫氶亾锛夈��
+ * <p>
+ * 鈿狅笍 璇ラ�氶亾鏈変袱涓櫌鍖恒�佷袱濂楃煭淇$鍚嶏紝蹇呴』鍖哄垎寮�锛�
+ * <ul>
+ *   <li>{@link SmsSendRequest#getCampus()} 涓� {@code "1"} 鈫� 婀栨花闄㈠尯锛坽@code smsUtils.sendSms1}锛夛紱</li>
+ *   <li>鍏朵粬锛堝惈涓虹┖锛夆啋 鍚村北闄㈠尯锛坽@code smsUtils.sendSms}锛夈��</li>
+ * </ul>
+ * 鍒ゅ畾渚濇嵁鏉ヨ嚜 {@code RyTask} 涓�氳繃 {@code SysDept.campusid} 鏌ュ埌鐨勯櫌鍖虹紪鐮侊紝
+ * 璋冪敤鏂硅礋璐f妸 {@code campus} 浼犺繘鏉ワ紱涓嶄紶鍒欎繚鎸佷笌绾夸笂銆岄潪婀栨花鍗冲惔灞便�嶄竴鑷寸殑榛樿琛屼负銆�
+ * <p>
+ * 鎴愬姛鍒ゅ畾锛氱綉鍏宠繑鍥炲瓧绗︿覆鍖呭惈銆屽鐞嗘垚鍔熴�嶃��
+ * 浠g爜鏉ユ簮锛歿@code RyTask.hzszlyy 鍒嗘敮}锛堣涓轰繚鎸佷笉鍙橈級銆�
+ */
+@Slf4j
+@Component
+public class ShiyiSmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key锛屼笌 {@code spring.profiles.active=hzszlyy} 瀵瑰簲
+     */
+    public static final String KEY = "hzszlyy";
+
+    /**
+     * 闄㈠尯缂栫爜锛氭箹婊�
+     */
+    public static final String CAMPUS_HIBIN = "1";
+
+    private final ShiyiSmsApi shiyiSmsApi;
+
+    public ShiyiSmsSender(ShiyiSmsApi shiyiSmsApi) {
+        this.shiyiSmsApi = shiyiSmsApi;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "鏉窞甯備竴鐭俊锛堝惔灞�/婀栨花涓ゅ绛惧悕锛�";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) {
+        boolean hibin = CAMPUS_HIBIN.equals(request.getCampus());
+        String result = hibin
+                ? shiyiSmsApi.sendHibin(request.getPhone(), request.getContent())
+                : shiyiSmsApi.sendWushan(request.getPhone(), request.getContent());
+
+        log.info("銆恵}銆戝競涓�鐭俊鍙戦�佺粨鏋滐紙{}锛夛細{}", KEY, hibin ? "婀栨花" : "鍚村北", result);
+        if (StringUtils.isNotEmpty(result) && result.contains("澶勭悊鎴愬姛")) {
+            return SendResult.success(KEY, MessageChannel.SMS, result).withCode(result);
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", result).withCode(result);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.java
new file mode 100644
index 0000000..913e8fd
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.java
@@ -0,0 +1,114 @@
+package com.ruoyi.message.sms.provider.ls;
+
+/**
+ * 涓芥按鐭俊鏈烘瀯绾ч厤缃��
+ * <p>
+ * 鍘熷疄鐜版湁涓夊鏌ヨ鏂瑰紡锛坽@code RyTask} 鎸夋満鏋勬煡 {@code ls.msg.info}銆�
+ * {@code ServiceSubtaskServiceImpl} 鐢� {@code MsgLSEnum}銆�
+ * {@code SmsRecordsServiceImpl} 鍙堟槸绗笁濂楋級锛岃繖閲岀粺涓�涓轰竴涓�煎璞°��
+ */
+public class LishuiMessageConfig {
+
+    /**
+     * 娑堟伅鍙戦�佸湴鍧�
+     */
+    private String address;
+
+    /**
+     * 绉熸埛ID锛堟姤鏂� XiaoXiTou.ZuHuID锛�
+     */
+    private String zuHuId;
+
+    /**
+     * 绉熸埛鍚嶇О锛堟姤鏂� XiaoXiTou.ZuHuMC / FaSongJGMC锛�
+     */
+    private String zuHuMc;
+
+    /**
+     * 鍙戦�佹満鏋処D锛堟姤鏂� XiaoXiTou.FaSongJGID锛�
+     */
+    private String orgid;
+
+    /**
+     * 鍙戦�佷汉ID
+     */
+    private String sendPersonId;
+
+    /**
+     * 鍙戦�佷汉濮撳悕
+     */
+    private String sendPersonName;
+
+    /**
+     * token 鑾峰彇鍦板潃
+     */
+    private String tokenUrl;
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getZuHuId() {
+        return zuHuId;
+    }
+
+    public void setZuHuId(String zuHuId) {
+        this.zuHuId = zuHuId;
+    }
+
+    public String getZuHuMc() {
+        return zuHuMc;
+    }
+
+    public void setZuHuMc(String zuHuMc) {
+        this.zuHuMc = zuHuMc;
+    }
+
+    public String getOrgid() {
+        return orgid;
+    }
+
+    public void setOrgid(String orgid) {
+        this.orgid = orgid;
+    }
+
+    public String getSendPersonId() {
+        return sendPersonId;
+    }
+
+    public void setSendPersonId(String sendPersonId) {
+        this.sendPersonId = sendPersonId;
+    }
+
+    public String getSendPersonName() {
+        return sendPersonName;
+    }
+
+    public void setSendPersonName(String sendPersonName) {
+        this.sendPersonName = sendPersonName;
+    }
+
+    public String getTokenUrl() {
+        return tokenUrl;
+    }
+
+    public void setTokenUrl(String tokenUrl) {
+        this.tokenUrl = tokenUrl;
+    }
+
+    @Override
+    public String toString() {
+        return "LishuiMessageConfig{address='" + address + '\''
+                + ", zuHuId='" + zuHuId + '\''
+                + ", zuHuMc='" + zuHuMc + '\''
+                + ", orgid='" + orgid + '\''
+                + ", sendPersonId='" + sendPersonId + '\''
+                + ", sendPersonName='" + sendPersonName + '\''
+                + ", tokenUrl='" + tokenUrl + '\''
+                + '}';
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.java
new file mode 100644
index 0000000..f93363a
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.java
@@ -0,0 +1,34 @@
+package com.ruoyi.message.sms.provider.ls;
+
+/**
+ * 涓芥按鏈烘瀯绾ч厤缃� / token 鎻愪緵鏂癸紙鎵╁睍鐐� SPI锛夈��
+ * <p>
+ * 鐜扮姸锛氫附姘寸殑銆岀煭淇″湴鍧� / 绉熸埛淇℃伅 / 鍙戦�佷汉銆嶅瓨鍦ㄦ暟鎹簱琛� {@code sys_config} 鐨� {@code ls.msg.info} 閲岋紝
+ * 鑰岃〃璁块棶鍦� {@code ruoyi-system} / {@code smartor} 妯″潡锛泃oken 鎹㈠彇閫昏緫鍦� {@code smartor} 鐨�
+ * {@code LSHospTokenUtil}銆�
+ * <p>
+ * 涓轰簡璁� {@code ruoyi-message} 淇濇寔銆屼笉渚濊禆涓氬姟妯″潡銆嶇殑骞插噣鍒嗗眰锛岃繖閲屽畾涔� SPI锛�
+ * 鐢变笟鍔℃ā鍧楋紙smartor锛夊疄鐜板苟娉ㄥ唽涓� Spring Bean锛涜嫢瀹瑰櫒閲屾病鏈夊疄鐜帮紝鏈ā鍧椾細閫�鍖栦负浣跨敤
+ * 浠g爜鍐呴潤鎬侀厤缃紙绛変环浜� {@code MsgLSEnum}锛変笖涓嶆崲 token銆�
+ * <p>
+ * 鎺ㄨ崘瀹炵幇鏀惧湪 smartor 妯″潡锛屽唴閮ㄩ�氳繃 {@code ISysConfigService} 鏌ヨ {@code ls.msg.info}銆�
+ */
+public interface LishuiMessageConfigProvider {
+
+    /**
+     * 鏌ヨ鎸囧畾鏈烘瀯鐨勪附姘寸煭淇¢厤缃�
+     *
+     * @param orgid 鏈烘瀯ID
+     * @return 閰嶇疆锛涙煡涓嶅埌杩斿洖 {@code null}
+     */
+    LishuiMessageConfig getConfig(String orgid);
+
+    /**
+     * 鑾峰彇涓芥按 360 骞冲彴 token
+     *
+     * @param orgid    鏈烘瀯ID
+     * @param tokenUrl token 鑾峰彇鍦板潃
+     * @return token锛涜幏鍙栧け璐ヨ繑鍥� {@code null}
+     */
+    String getToken(String orgid, String tokenUrl);
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.java
new file mode 100644
index 0000000..627cf01
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.java
@@ -0,0 +1,149 @@
+package com.ruoyi.message.sms.provider.ls;
+
+import com.alibaba.fastjson2.JSON;
+import com.google.gson.Gson;
+import com.ruoyi.common.utils.OkHttpExample;
+import com.ruoyi.common.utils.uuid.IdUtils;
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 涓芥按鐭俊鍙戦�佹柟锛坽@code ls} 閫氶亾锛屼附姘� 13 瀹跺尰闄級銆�
+ * <p>
+ * 瀵规帴鐗瑰緛锛堜笌鍏朵粬閫氶亾宸紓鏈�澶х殑涓�涓級锛�
+ * <ul>
+ *   <li>鎶ユ枃涓� {@code XiaoXiTou + YeWuXX.DuanXinXX} 鐨勫祵濂� JSON锛�</li>
+ *   <li>闇�瑕佸厛鐢� {@code LyraTokenUtil} 鎹� token锛屽啀浠� header 浼� token锛�</li>
+ *   <li>鏈烘瀯鍦板潃/绉熸埛/鍙戦�佷汉瀛樺湪 {@code sys_config} 琛ㄧ殑 {@code ls.msg.info} 閲岋紙鎸夋満鏋勬煡璇級锛�</li>
+ *   <li>鎴愬姛鍒ゅ畾涓哄搷搴斾綋 {@code Code == "0"}銆�</li>
+ * </ul>
+ * 浠g爜鏉ユ簮锛歿@code RyTask.ls 鍒嗘敮} + {@code RyTask.getDXCode}锛堣涓轰繚鎸佷笉鍙橈級銆�
+ */
+@Slf4j
+@Component
+public class LishuiSmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key锛屼笌 {@code spring.profiles.active=ls} 瀵瑰簲
+     */
+    public static final String KEY = "ls";
+
+    private final ObjectProvider<LishuiMessageConfigProvider> configProvider;
+
+    public LishuiSmsSender(ObjectProvider<LishuiMessageConfigProvider> configProvider) {
+        this.configProvider = configProvider;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "涓芥按鐭俊锛�13瀹跺尰闄紝token + 鏈烘瀯绾ч厤缃級";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) throws Exception {
+        LishuiMessageConfig config = resolveConfig(request.getOrgid());
+        if (config == null || StringUtils.isEmpty(config.getAddress())) {
+            //涓庣嚎涓婅涓轰竴鑷达細璇ユ満鏋勬病鏈夐厤缃煭淇″湴鍧�锛岃涓哄彂閫佸け璐�
+            return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�,璇ユ満鏋勬病鏈夐厤缃煭淇″湴鍧�", null);
+        }
+
+        String token = resolveToken(request.getOrgid(), config);
+        Map<String, Object> body = buildBody(request, config);
+
+        log.info("銆恵}銆戜附姘寸煭淇″彂閫侊紝鍦板潃锛歿}锛屽弬鏁帮細{}锛屾満鏋処D锛歿}",
+                KEY, config.getAddress(), request, request.getOrgid());
+        String result = OkHttpExample.sendPostRequest(config.getAddress(), new Gson().toJson(body), token);
+        log.info("銆恵}銆戜附姘寸煭淇″彂閫佺粨鏋滐細{}", KEY, result);
+
+        if (StringUtils.isEmpty(result)) {
+            return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", result);
+        }
+        Map<String, Object> textParam = JSON.parseObject(result, Map.class);
+        Object codeObj = textParam == null ? null : textParam.get("Code");
+        String code = codeObj == null ? null : codeObj.toString();
+        if ("0".equals(code)) {
+            return SendResult.success(KEY, MessageChannel.SMS, result).withCode(code);
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", result).withCode(code);
+    }
+
+    /**
+     * 浼樺厛浣跨敤涓氬姟妯″潡娉ㄥ唽鐨� {@link LishuiMessageConfigProvider}锛堟煡 sys_config锛夛紝
+     * 鍚﹀垯閫�鍖栦负浠g爜鍐呴潤鎬侀厤缃��
+     */
+    private LishuiMessageConfig resolveConfig(String orgid) {
+        LishuiMessageConfigProvider provider = configProvider.getIfAvailable();
+        if (provider != null) {
+            LishuiMessageConfig config = provider.getConfig(orgid);
+            if (config != null) {
+                if (StringUtils.isEmpty(config.getOrgid())) {
+                    config.setOrgid(orgid);
+                }
+                return config;
+            }
+        }
+        LishuiMessageConfig fallback = LishuiStaticConfig.fallback(orgid);
+        return fallback;
+    }
+
+    private String resolveToken(String orgid, LishuiMessageConfig config) {
+        if (StringUtils.isEmpty(config.getTokenUrl())) {
+            return null;
+        }
+        LishuiMessageConfigProvider provider = configProvider.getIfAvailable();
+        if (provider == null) {
+            log.warn("銆恵}銆戞湭鎵惧埌 LishuiMessageConfigProvider 瀹炵幇锛屾棤娉曟崲鍙� token锛屽皢浠ョ┖ token 璋冪敤", KEY);
+            return null;
+        }
+        return provider.getToken(orgid, config.getTokenUrl());
+    }
+
+    /**
+     * 缁勮涓芥按鎶ユ枃锛歿@code XiaoXiTou + YeWuXX.DuanXinXX}锛堜笌 {@code RyTask.getDXCode} 瀹屽叏涓�鑷达級
+     */
+    private Map<String, Object> buildBody(SmsSendRequest request, LishuiMessageConfig config) {
+        Map<String, Object> headerMap = new LinkedHashMap<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        headerMap.put("XiaoXiID", IdUtils.simpleUUID());
+        headerMap.put("FaSongSJ", sdf.format(new Date()));
+        headerMap.put("ZuHuID", config.getZuHuId());
+        headerMap.put("ZuHuMC", config.getZuHuMc());
+        headerMap.put("FaSongJGID", config.getOrgid());
+        headerMap.put("FaSongJGMC", config.getZuHuMc());
+        headerMap.put("FaSongXTJC", "SUIFANGXT");
+        headerMap.put("FaSongXTMC", "闅忚绯荤粺");
+        headerMap.put("FaSongFCSJC", "ZJHES");
+        headerMap.put("XiaoXiLX", "FZ_PT_DuanXinFS");
+        headerMap.put("XiaoXiMC", "鐭俊鍙戦��");
+
+        Map<String, Object> duanXinXX = new LinkedHashMap<>();
+        duanXinXX.put("ShouJiHM", request.getPhone());
+        duanXinXX.put("FaSongNR", request.getContent());
+        duanXinXX.put("FaSongRID", config.getSendPersonId());
+        duanXinXX.put("FaSongRXM", config.getSendPersonName());
+
+        Map<String, Object> yeWuXX = new LinkedHashMap<>();
+        yeWuXX.put("DuanXinXX", duanXinXX);
+
+        Map<String, Object> body = new LinkedHashMap<>();
+        body.put("XiaoXiTou", headerMap);
+        body.put("YeWuXX", yeWuXX);
+        return body;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.java
new file mode 100644
index 0000000..b6be640
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.java
@@ -0,0 +1,27 @@
+package com.ruoyi.message.sms.provider.ls;
+
+/**
+ * 涓芥按鏈烘瀯閰嶇疆鐨勯潤鎬佸厹搴曘��
+ * <p>
+ * 璇存槑锛氬師 {@code com.ruoyi.common.enums.MsgLSEnum} 閲屼袱涓満鏋勶紙鏅畞銆佷附姘村競涓尰闄級
+ * 鐨勫叿浣撳湴鍧�/绉熸埛/鍙戦�佷汉閰嶇疆宸茶鏁存娉ㄩ噴鎺夛紝绾夸笂瀹為檯渚濊禆 {@code sys_config} 琛ㄧ殑
+ * {@code ls.msg.info}锛堣 {@code RyTask.ls 鍒嗘敮} 涓� {@code SmsRecordsServiceImpl.sendSMS}锛夈��
+ * <p>
+ * 鍥犳杩欓噷涓嶅仛闈欐�佸厹搴曪細闈欐�佸厹搴曚竴鏃︾粰鍑恒�屽湴鍧�涓虹┖銆嶇殑閰嶇疆锛屽弽鑰屼細鎶婄嚎涓婂師鏈兘姝e父
+ * 鎹㈠彇 token 鐨勬祦绋嬫墦鏂紙瑙� {@link LishuiSmsSender#resolveConfig}锛夈��
+ * 鑻ョ‘瀹為渶瑕侀潤鎬侀厤缃紝璇峰疄鐜� {@link LishuiMessageConfigProvider}锛堟帹鑽愶紝璧� {@code sys_config}锛夈��
+ * <p>
+ * 淇濈暀鏈被鏄负浜嗘爣娉ㄨ鍘嗗彶閬楃暀鐐癸紝閬垮厤鍚庝汉閲嶅韪╁潙銆�
+ */
+final class LishuiStaticConfig {
+
+    private LishuiStaticConfig() {
+    }
+
+    /**
+     * 姘歌繙杩斿洖 {@code null}锛岃〃绀恒�屾病鏈夐潤鎬佸厹搴曘�嶏紝鐢辫皟鐢ㄦ柟鍐冲畾濡備綍澶勭悊銆�
+     */
+    static LishuiMessageConfig fallback(String orgid) {
+        return null;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.java
new file mode 100644
index 0000000..9d650c5
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.java
@@ -0,0 +1,76 @@
+package com.ruoyi.message.sms.provider.messaginginsert;
+
+import com.ruoyi.message.config.MessageProperties;
+import com.ruoyi.message.sms.provider.messaginginsert.ws.MessagingInsertLocator;
+import com.ruoyi.message.sms.provider.messaginginsert.ws.MessagingInsertSoap12Stub;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.xml.rpc.holders.IntHolder;
+import javax.xml.rpc.holders.StringHolder;
+import java.util.Date;
+
+/**
+ * 棰勭害鎸傚彿鐭俊骞冲彴锛圡essagingInsert锛堿PI銆�
+ * <p>
+ * 瀵规帴鐗瑰緛锛欰xis SOAP12锛寋@code SMSMessageAccept(xmlReq, out int, out string)}锛�
+ * 璇锋眰鎶ユ枃涓� {@code &lt;Request&gt;&lt;operate&gt;S001&lt;/operate&gt;...} 鐨� XML銆�
+ * <p>
+ * 杩佺Щ璇存槑锛氬師閫昏緫鍦� {@code com.ruoyi.system.service.impl.SmsParamServiceImpl.sendSmsInfo}锛�
+ * 鐜版敹鍙e埌鏈ā鍧楋紱鍘熷疄鐜版妸鏈嶅姟鍦板潃纭紪鐮佸湪鐢熸垚鐨� {@code MessagingInsertLocator} 閲岋紝
+ * 杩欓噷鏀逛负鎸� {@code message.sms.messaging-insert.ws-url} 鏄惧紡璁剧疆锛堥粯璁ゅ�间笌鍘熺‖缂栫爜涓�鑷达級銆�
+ */
+@Slf4j
+@Component
+public class MessagingInsertSmsApi {
+
+    private final MessageProperties properties;
+
+    public MessagingInsertSmsApi(MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * 鍙戦�侀绾︽寕鍙风被鐭俊锛坥perate=S001锛孴ype=棰勭害鎸傚彿锛�
+     *
+     * @param content 鐭俊鍐呭
+     * @param phone   鎵嬫満鍙�
+     * @return 骞冲彴杩斿洖鐮�
+     */
+    public Integer sendSmsInfo(String content, String phone) {
+        MessagingInsertSoap12Stub binding;
+        try {
+            MessagingInsertLocator locator = new MessagingInsertLocator();
+            String wsUrl = properties.getSms().getMessagingInsert().getWsUrl();
+            if (wsUrl != null && !wsUrl.trim().isEmpty()) {
+                locator.setMessagingInsertSoap12EndpointAddress(wsUrl);
+                locator.setMessagingInsertSoapEndpointAddress(wsUrl);
+            }
+            binding = (MessagingInsertSoap12Stub) locator.getMessagingInsertSoap12();
+        } catch (Exception e) {
+            log.error("銆怣essagingInsertSmsApi銆戝垵濮嬪寲 SOAP 瀹㈡埛绔け璐ワ細{}", e.getMessage(), e);
+            return null;
+        }
+
+        String xmlReq = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+                + "<Request>\n"
+                + "<operate>S001</operate>\n"
+                + "<Sheets>\n"
+                + "<Sheet>\n"
+                + "<Content>" + content + "</Content>\n"
+                + "<Mobile>" + phone + "</Mobile>\n"
+                + "<DateTime>" + new Date() + "</DateTime>\n"
+                + "<Type>棰勭害鎸傚彿</Type>\n"
+                + "</Sheet>\n"
+                + "</Sheets>\n"
+                + "</Request>";
+
+        Integer result = null;
+        try {
+            result = binding.SMSMessageAccept(xmlReq, new IntHolder(), new StringHolder());
+        } catch (Exception e) {
+            log.error("銆怣essagingInsertSmsApi銆戠煭淇″彂閫佸け璐ワ細{}", e.getMessage(), e);
+        }
+        return result;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.java
new file mode 100644
index 0000000..76e85ba
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.java
@@ -0,0 +1,54 @@
+package com.ruoyi.message.sms.provider.messaginginsert;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 棰勭害鎸傚彿鐭俊骞冲彴鍙戦�佹柟锛坽@code messaging-insert} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛欰xis SOAP12 {@code SMSMessageAccept(XML)}锛岃繑鍥� int銆�
+ * <p>
+ * 璇存槑锛氳閫氶亾鐩墠鍙湪 {@code SmsParamServiceImpl.sendSmsInfo} 閲屼娇鐢紙棰勭害鎸傚彿閫氱煡鐭俊锛夛紝
+ * 涓氬姟闅忚娴佺▼鏈蛋瀹冦�傛敹鍙e悗鍙敱宸ュ巶缁熶竴璋冨害銆�
+ */
+@Slf4j
+@Component
+public class MessagingInsertSmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key
+     */
+    public static final String KEY = "messaging-insert";
+
+    private final MessagingInsertSmsApi messagingInsertSmsApi;
+
+    public MessagingInsertSmsSender(MessagingInsertSmsApi messagingInsertSmsApi) {
+        this.messagingInsertSmsApi = messagingInsertSmsApi;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "棰勭害鎸傚彿鐭俊骞冲彴锛圡essagingInsert锛孉xis SOAP12锛�";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) {
+        Integer code = messagingInsertSmsApi.sendSmsInfo(request.getContent(), request.getPhone());
+        String codeStr = code == null ? null : code.toString();
+        //TODO 寰呯‘璁わ細鍘熷疄鐜版湭瀵硅繑鍥� int 鍋氭垚鍔熷垽瀹氾紝鍙妸 int 鍚戜笂杩斿洖銆�
+        //     杩欓噷鎸夈�岄潪绌哄嵆鎴愬姛銆嶅鐞嗕互淇濇寔琛屼负锛堣皟鐢ㄦ柟鍘熸湰涔熶笉鍒ゆ柇锛夛紝纭杩斿洖鐮佽涔夊悗搴旀敼涓虹簿纭垽瀹氥��
+        if (code != null) {
+            return SendResult.success(KEY, MessageChannel.SMS, codeStr).withCode(codeStr);
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", null);
+    }
+}
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsert.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.java
similarity index 92%
rename from ruoyi-system/src/main/java/WebServiceClient/MessagingInsert.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.java
index bf446d3..c9b57ce 100644
--- a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsert.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.java
@@ -5,7 +5,7 @@
  * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
  */
 
-package WebServiceClient;
+package com.ruoyi.message.sms.provider.messaginginsert.ws;
 
 public interface MessagingInsert extends javax.xml.rpc.Service {
     public String getMessagingInsertSoap12Address();
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertLocator.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.java
similarity index 98%
rename from ruoyi-system/src/main/java/WebServiceClient/MessagingInsertLocator.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.java
index 2c52b13..e40b36a 100644
--- a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertLocator.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.java
@@ -5,7 +5,7 @@
  * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
  */
 
-package WebServiceClient;
+package com.ruoyi.message.sms.provider.messaginginsert.ws;
 
 public class MessagingInsertLocator extends org.apache.axis.client.Service implements MessagingInsert {
 
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap12Stub.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.java
similarity index 98%
rename from ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap12Stub.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.java
index 496334e..554664e 100644
--- a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap12Stub.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.java
@@ -5,7 +5,7 @@
  * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
  */
 
-package WebServiceClient;
+package com.ruoyi.message.sms.provider.messaginginsert.ws;
 
 public class MessagingInsertSoap12Stub extends org.apache.axis.client.Stub implements MessagingInsertSoap_PortType {
     private java.util.Vector cachedSerClasses = new java.util.Vector();
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap_BindingStub.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.java
similarity index 98%
rename from ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap_BindingStub.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.java
index 1d6f833..42a6011 100644
--- a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap_BindingStub.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.java
@@ -5,7 +5,7 @@
  * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
  */
 
-package WebServiceClient;
+package com.ruoyi.message.sms.provider.messaginginsert.ws;
 
 import org.apache.axis.client.Stub;
 
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap_PortType.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.java
similarity index 87%
rename from ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap_PortType.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.java
index d1068ed..9cbadd2 100644
--- a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertSoap_PortType.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.java
@@ -5,7 +5,7 @@
  * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
  */
 
-package WebServiceClient;
+package com.ruoyi.message.sms.provider.messaginginsert.ws;
 
 public interface MessagingInsertSoap_PortType extends java.rmi.Remote {
     public Integer SMSMessageAccept(String xmlReq, javax.xml.rpc.holders.IntHolder SMSMessageAcceptResult, javax.xml.rpc.holders.StringHolder xmlResp) throws java.rmi.RemoteException;
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.java
new file mode 100644
index 0000000..fc1e112
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.java
@@ -0,0 +1,74 @@
+package com.ruoyi.message.sms.provider.nhfy;
+
+/**
+ * MT 娑堟伅鍙戦�佸搷搴斿弬鏁帮紙琛屼笟姹囪仛骞冲彴 {@code /submitsm} 鐨勮繑鍥炰綋锛夈��
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.smartor.domain.MtSubmitSmResp}锛岄殢鍙戦�佹柟鏀跺彛鍒� {@code ruoyi-message}銆�
+ */
+public class MtSubmitSmResp {
+
+    /**
+     * 涓嬪彂鐘舵�侊紝0 鎴愬姛锛屽叾浠栧け璐�
+     */
+    private Integer code;
+
+    /**
+     * 澶辫触鏃剁殑閿欒鎻愮ず
+     */
+    private String message;
+
+    /**
+     * 澶辫触鏃剁殑閿欒鎻愮ず
+     */
+    private String success;
+
+    /**
+     * 鍝嶅簲缁撴灉
+     */
+    private String result;
+
+    /**
+     * 涓嬪彂鐘舵��=0鏃舵湁鏁堬紝涓虹郴缁熶骇鐢熺殑 msgid锛屽鍙戠敓浜嗛暱鐭俊鎷嗗垎锛屽垯杩斿洖澶氭潯 msgid
+     */
+    private java.util.List<String> mtSubmitSm;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getSuccess() {
+        return success;
+    }
+
+    public void setSuccess(String success) {
+        this.success = success;
+    }
+
+    public String getResult() {
+        return result;
+    }
+
+    public void setResult(String result) {
+        this.result = result;
+    }
+
+    public java.util.List<String> getMtSubmitSm() {
+        return mtSubmitSm;
+    }
+
+    public void setMtSubmitSm(java.util.List<String> mtSubmitSm) {
+        this.mtSubmitSm = mtSubmitSm;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.java
new file mode 100644
index 0000000..7487dd7
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.java
@@ -0,0 +1,127 @@
+package com.ruoyi.message.sms.provider.nhfy;
+
+import com.alibaba.fastjson2.JSON;
+import com.ruoyi.message.config.MessageProperties;
+import com.ruoyi.message.config.MtSmsConfig;
+import com.ruoyi.message.config.RootMessageProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * MT娑堟伅鍙戦�佸伐鍏风被锛圫P 鍚戣涓氭眹鑱氬钩鍙版彁浜� MT 娑堟伅锛夈��
+ * <p>
+ * 鎺ュ彛鍦板潃锛歿@code http://ip:port/submitsm}锛涚紪鐮侊細UTF-8锛涢壌鏉冪畻娉曪細MD5銆�
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.smartor.common.MtSubmitSmUtil}锛坽@code @Component} + {@code @Value} 娉ㄥ叆锛夛紝
+ * 杩佺Щ鍚庨厤缃敼涓轰粠 {@link MessageProperties} 璇诲彇锛堝簳灞備粛鏄悓涓�鎵� configuration key锛夛紝琛屼负涓嶅彉銆�
+ */
+@Slf4j
+@Component
+public class MtSubmitSmUtil {
+
+    private static final RestTemplate REST_TEMPLATE = new RestTemplate();
+
+    private final MessageProperties properties;
+
+    public MtSubmitSmUtil(MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * 鍙戦�� MT 娑堟伅
+     *
+     * @param destAddr 鐩爣鍙风爜
+     * @param content  鐭俊鍐呭
+     * @return 鍝嶅簲缁撴灉
+     */
+    public Map<String, Object> submitSm(String destAddr, String content) {
+        MtSmsConfig mt = properties.getSms().getMt();
+        try {
+            log.info("鍗楀崕闄勪竴鍙戦�佺煭淇★紝destAddr锛歿}锛宑ontent锛歿}", destAddr, content);
+            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+            String hashHex = buildHashHex(mt.getAccountName(), mt.getPassword(), date);
+
+            Map<String, Object> authMap = new HashMap<>();
+            authMap.put("Algorithm", "MD5");
+            authMap.put("Date", date);
+            authMap.put("HASHHEX", hashHex);
+
+            Map<String, Object> reqMap = new HashMap<>();
+            reqMap.put("accountName", mt.getAccountName());
+            reqMap.put("Authorization", authMap);
+            reqMap.put("DestAddr", destAddr);
+            reqMap.put("SourceAddr", mt.getSourceAddr());
+            reqMap.put("Content", mt.getFlag() + content);
+            reqMap.put("ServiceCode", mt.getServiceCode());
+
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
+            headers.set("Accept-Language", "UTF-8");
+            //TODO 寰呯‘璁わ細鍘熷疄鐜版妸 app-key 鍐欐涓� ak-BFq4NN0TMf92J7KAioNYGz74锛�
+            //     鑰� yml 閲屽悓鏃跺瓨鍦� sms_appkey 閰嶇疆椤瑰嵈鏈浣跨敤銆傝繖閲屼负淇濇寔绾夸笂琛屼负浠嶇敤鍘熺‖缂栫爜鍊硷紝
+            //     寤鸿鏀逛负璇诲彇 mt.getAppkey()锛堝凡鏀寔锛夊苟纭鍝釜鎵嶆槸姝g‘鐨� app-key銆�
+            headers.set("app-key", "ak-BFq4NN0TMf92J7KAioNYGz74");
+
+            HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(reqMap), headers);
+            log.info("MtSubmitSm 璇锋眰鍦板潃锛歿}锛岃姹傚弬鏁帮細{}", mt.getUrl() + "/submitsm", JSON.toJSONString(reqMap));
+
+            ResponseEntity<String> response = REST_TEMPLATE.postForEntity(mt.getUrl(), entity, String.class);
+            log.info("MtSubmitSm 鍝嶅簲缁撴灉锛歿}", response.getBody());
+
+            return JSON.parseObject(response.getBody(), Map.class);
+        } catch (Exception e) {
+            log.error("MtSubmitSm 鍙戦�佸け璐ワ紝url锛歿}锛宒estAddr锛歿}锛宔rror锛歿}", mt.getUrl(), destAddr, e.getMessage(), e);
+            Map<String, Object> resp = new HashMap<>();
+            resp.put("code", -1);
+            resp.put("message", "鍙戦�佸紓甯革細" + e.getMessage());
+            return resp;
+        }
+    }
+
+    /**
+     * 璁$畻 HASHHEX锛歁D5(Algorithm:甯愬彿鍚�:瀵嗙爜:Date)
+     * <p>
+     * 渚嬶細{@code MD5:95555:12345:2016-10-09 16:19:43}
+     */
+    private static String buildHashHex(String accountName, String password, String date) throws Exception {
+        String plain = "MD5:" + accountName + ":" + password + ":" + date;
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        byte[] bytes = md.digest(plain.getBytes(StandardCharsets.UTF_8));
+        StringBuilder sb = new StringBuilder();
+        for (byte b : bytes) {
+            sb.append(String.format("%02x", b));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 鍒ゆ柇 MT 鍝嶅簲鏄惁鎴愬姛锛坽@code result == "0"}锛�
+     */
+    public static boolean isSuccess(Map<String, Object> resp) {
+        if (resp == null) {
+            return false;
+        }
+        Object result = resp.get("result");
+        return result != null && "0".equals(result.toString());
+    }
+
+    /**
+     * 鍒ゆ柇鍝嶅簲鐨� result 瀛楁鏄惁涓虹┖
+     */
+    public static boolean hasResult(Map<String, Object> resp) {
+        return resp != null && StringUtils.isNotEmpty(String.valueOf(resp.get("result")));
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.java
new file mode 100644
index 0000000..92795b3
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.java
@@ -0,0 +1,56 @@
+package com.ruoyi.message.sms.provider.nhfy;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * 鍗楀崕闄勪竴鐭俊鍙戦�佹柟锛坽@code nhfy} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛歊EST + 琛屼笟姹囪仛骞冲彴 {@code /submitsm}锛岄壌鏉� {@code HASHHEX = MD5(MD5:璐﹀彿:瀵嗙爜:鏃堕棿)}锛�
+ * 鎴愬姛鍒ゅ畾涓哄搷搴� {@code result == "0"}銆�
+ * 浠g爜鏉ユ簮锛歿@code RyTask.nhfy 鍒嗘敮} + {@code RedisMqReceiver.nhfy 鍒嗘敮} + {@code SmsController} + {@code smsSubTask}銆�
+ */
+@Slf4j
+@Component
+public class NhfySmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key锛屼笌 {@code spring.profiles.active=nhfy} 瀵瑰簲
+     */
+    public static final String KEY = "nhfy";
+
+    private final MtSubmitSmUtil mtSubmitSmUtil;
+
+    public NhfySmsSender(MtSubmitSmUtil mtSubmitSmUtil) {
+        this.mtSubmitSmUtil = mtSubmitSmUtil;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "鍗楀崕闄勪竴鐭俊锛堣涓氭眹鑱氬钩鍙� /submitsm锛�";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) {
+        Map<String, Object> resp = mtSubmitSmUtil.submitSm(request.getPhone(), request.getContent());
+        log.info("銆恵}銆戝崡鍗庨檮涓�鐭俊鍙戦�佺粨鏋滐細{}", KEY, resp);
+
+        Object result = resp == null ? null : resp.get("result");
+        String code = result == null ? null : result.toString();
+        if (MtSubmitSmUtil.isSuccess(resp)) {
+            return SendResult.success(KEY, MessageChannel.SMS, String.valueOf(resp)).withCode(code);
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", String.valueOf(resp)).withCode(code);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.java
new file mode 100644
index 0000000..da8c66b
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.java
@@ -0,0 +1,65 @@
+package com.ruoyi.message.sms.provider.shiyi;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鏉窞甯備竴 HIS 骞冲彴鐭俊鍙戦�佹柟锛坽@code shiyi-his} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛歐CF SOAP {@code RunService(TradeType=FASONGDX)}锛屾姤鏂囦綋涓� XML锛�
+ * 鎴愬姛鍒ゅ畾涓哄搷搴� {@code ERRNO == "0"}銆�
+ * <p>
+ * 璇存槑锛氳閫氶亾鐩墠<b>杩樻病鏈変笟鍔¤皟鐢ㄧ偣</b>锛堝彧鏈� {@code /sms/sendShiyiTest} 娴嬭瘯鎺ュ彛锛夛紝
+ * 鏀跺彛鍒版湰妯″潡鍚庡彲鐢卞伐鍘傜粺涓�璋冨害銆�
+ * 浠g爜鏉ユ簮锛氬師 {@code com.smartor.common.ShiyiSmsUtil}锛堣涓轰繚鎸佷笉鍙橈級銆�
+ */
+@Slf4j
+@Component
+public class ShiyiHisSmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key锛堜笉鏄� profile 鍚嶏紝鍥犱负褰撳墠绔欑偣閮戒細璧拌嚜宸辩殑閫氶亾锛�
+     */
+    public static final String KEY = "shiyi-his";
+
+    private final ShiyiSmsUtil shiyiSmsUtil;
+
+    public ShiyiHisSmsSender(ShiyiSmsUtil shiyiSmsUtil) {
+        this.shiyiSmsUtil = shiyiSmsUtil;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "鏉窞甯備竴 HIS 骞冲彴鐭俊锛圵CF SOAP FASONGDX锛�";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) {
+        ShiyiSmsRequest smsRequest = new ShiyiSmsRequest();
+        smsRequest.setShoujihao(request.getPhone());
+        smsRequest.setDuanxinnr(request.getContent());
+        smsRequest.setJigoudm(request.getOrgid());
+        if (request.getTemplateCode() != null) {
+            smsRequest.setDuanxinlx(request.getTemplateCode());
+        }
+
+        ShiyiSmsResponse response = shiyiSmsUtil.sendSms(smsRequest);
+        if (response.isSuccess()) {
+            return SendResult.success(KEY, MessageChannel.SMS, response.getRawXml())
+                    .withCode(response.getErrno())
+                    .withMessage(response.getErrmsg());
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS,
+                "鐭俊鍙戦�佸け璐ワ細" + response.getErrmsg(), response.getRawXml())
+                .withCode(response.getErrno());
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.java
new file mode 100644
index 0000000..278d5f8
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.java
@@ -0,0 +1,197 @@
+package com.ruoyi.message.sms.provider.shiyi;
+
+/**
+ * 鏉窞甯備竴 HIS 鏈嶅姟骞冲彴 5.2 鐭俊涓氬姟 璇锋眰瀵硅薄 (FASONGDX)銆�
+ * <p>
+ * 瀵瑰簲 TradeMsg XML 鏍硅妭鐐� {@code FASONGDX_IN}銆�
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.smartor.domain.ShiyiSmsRequest}銆�
+ */
+public class ShiyiSmsRequest {
+
+    /** 鎿嶄綔鍛樹唬鐮� */
+    private String caozuoydm;
+
+    /** 鎿嶄綔鍛樺鍚� */
+    private String caozuoyxm;
+
+    /** 鎿嶄綔鏃ユ湡 yyyy-MM-dd HH:mm:ss */
+    private String caozuorq;
+
+    /** 绯荤粺鏍囪瘑 */
+    private String xitongbs;
+
+    /** 鍒嗛櫌浠g爜 */
+    private String fenyuandm;
+
+    /** 鏈烘瀯浠g爜 */
+    private String jigoudm;
+
+    /** 鏈烘瀯鍚嶇О */
+    private String jigoumc;
+
+    /** 鏈烘瀯楠岃瘉鐮� */
+    private String jigouyzm;
+
+    /** 鎺ユ敹鏈烘瀯浠g爜 */
+    private String jieshoujgdm;
+
+    /** 缁堢绾у埆 */
+    private String zhongduanjb;
+
+    /** 缁堢娴佹按 */
+    private String zhongduanls;
+
+    /** IP 鍦板潃 */
+    private String ipaddress;
+
+    /** 涓氬姟绫诲瀷 */
+    private String yewulx;
+
+    /** 鎺ュ叆鍦烘墍浠g爜 */
+    private String jierucsdm;
+
+    /** 鐭俊绫诲瀷 0锛氭櫘閫氱煭淇� */
+    private String duanxinlx;
+
+    /** 鎵嬫満鍙� */
+    private String shoujihao;
+
+    /** 鐭俊鍐呭 */
+    private String duanxinnr;
+
+    public String getCaozuoydm() {
+        return caozuoydm;
+    }
+
+    public void setCaozuoydm(String caozuoydm) {
+        this.caozuoydm = caozuoydm;
+    }
+
+    public String getCaozuoyxm() {
+        return caozuoyxm;
+    }
+
+    public void setCaozuoyxm(String caozuoyxm) {
+        this.caozuoyxm = caozuoyxm;
+    }
+
+    public String getCaozuorq() {
+        return caozuorq;
+    }
+
+    public void setCaozuorq(String caozuorq) {
+        this.caozuorq = caozuorq;
+    }
+
+    public String getXitongbs() {
+        return xitongbs;
+    }
+
+    public void setXitongbs(String xitongbs) {
+        this.xitongbs = xitongbs;
+    }
+
+    public String getFenyuandm() {
+        return fenyuandm;
+    }
+
+    public void setFenyuandm(String fenyuandm) {
+        this.fenyuandm = fenyuandm;
+    }
+
+    public String getJigoudm() {
+        return jigoudm;
+    }
+
+    public void setJigoudm(String jigoudm) {
+        this.jigoudm = jigoudm;
+    }
+
+    public String getJigoumc() {
+        return jigoumc;
+    }
+
+    public void setJigoumc(String jigoumc) {
+        this.jigoumc = jigoumc;
+    }
+
+    public String getJigouyzm() {
+        return jigouyzm;
+    }
+
+    public void setJigouyzm(String jigouyzm) {
+        this.jigouyzm = jigouyzm;
+    }
+
+    public String getJieshoujgdm() {
+        return jieshoujgdm;
+    }
+
+    public void setJieshoujgdm(String jieshoujgdm) {
+        this.jieshoujgdm = jieshoujgdm;
+    }
+
+    public String getZhongduanjb() {
+        return zhongduanjb;
+    }
+
+    public void setZhongduanjb(String zhongduanjb) {
+        this.zhongduanjb = zhongduanjb;
+    }
+
+    public String getZhongduanls() {
+        return zhongduanls;
+    }
+
+    public void setZhongduanls(String zhongduanls) {
+        this.zhongduanls = zhongduanls;
+    }
+
+    public String getIpaddress() {
+        return ipaddress;
+    }
+
+    public void setIpaddress(String ipaddress) {
+        this.ipaddress = ipaddress;
+    }
+
+    public String getYewulx() {
+        return yewulx;
+    }
+
+    public void setYewulx(String yewulx) {
+        this.yewulx = yewulx;
+    }
+
+    public String getJierucsdm() {
+        return jierucsdm;
+    }
+
+    public void setJierucsdm(String jierucsdm) {
+        this.jierucsdm = jierucsdm;
+    }
+
+    public String getDuanxinlx() {
+        return duanxinlx;
+    }
+
+    public void setDuanxinlx(String duanxinlx) {
+        this.duanxinlx = duanxinlx;
+    }
+
+    public String getShoujihao() {
+        return shoujihao;
+    }
+
+    public void setShoujihao(String shoujihao) {
+        this.shoujihao = shoujihao;
+    }
+
+    public String getDuanxinnr() {
+        return duanxinnr;
+    }
+
+    public void setDuanxinnr(String duanxinnr) {
+        this.duanxinnr = duanxinnr;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.java
new file mode 100644
index 0000000..6eb6a14
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.java
@@ -0,0 +1,79 @@
+package com.ruoyi.message.sms.provider.shiyi;
+
+/**
+ * 鏉窞甯備竴 HIS 鏈嶅姟骞冲彴 5.2 鐭俊涓氬姟 鍝嶅簲瀵硅薄 (FASONGDX_OUT)銆�
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.smartor.domain.ShiyiSmsResponse}銆�
+ */
+public class ShiyiSmsResponse {
+
+    /** 閿欒鍙凤紝0 鎴愬姛锛�1 澶辫触锛�2 HIS 寮傚父锛�99 鍙傛暟寮傚父锛�&lt;0 绯荤粺寮傚父 */
+    private String errno;
+
+    /** 閿欒鎻忚堪 */
+    private String errmsg;
+
+    /** 鎵╁睍閿欒鎻忚堪 */
+    private String errmsgex;
+
+    /** HIS 渚ф秷鎭� ID */
+    private String messageId;
+
+    /** 鐭俊 ID */
+    private String duanxinid;
+
+    /** 鍘熷鍝嶅簲 XML锛堣皟璇曠敤锛� */
+    private String rawXml;
+
+    public boolean isSuccess() {
+        return "0".equals(errno);
+    }
+
+    public String getErrno() {
+        return errno;
+    }
+
+    public void setErrno(String errno) {
+        this.errno = errno;
+    }
+
+    public String getErrmsg() {
+        return errmsg;
+    }
+
+    public void setErrmsg(String errmsg) {
+        this.errmsg = errmsg;
+    }
+
+    public String getErrmsgex() {
+        return errmsgex;
+    }
+
+    public void setErrmsgex(String errmsgex) {
+        this.errmsgex = errmsgex;
+    }
+
+    public String getMessageId() {
+        return messageId;
+    }
+
+    public void setMessageId(String messageId) {
+        this.messageId = messageId;
+    }
+
+    public String getDuanxinid() {
+        return duanxinid;
+    }
+
+    public void setDuanxinid(String duanxinid) {
+        this.duanxinid = duanxinid;
+    }
+
+    public String getRawXml() {
+        return rawXml;
+    }
+
+    public void setRawXml(String rawXml) {
+        this.rawXml = rawXml;
+    }
+}
diff --git a/smartor/src/main/java/com/smartor/common/ShiyiSmsUtil.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.java
similarity index 87%
rename from smartor/src/main/java/com/smartor/common/ShiyiSmsUtil.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.java
index e726987..d67417f 100644
--- a/smartor/src/main/java/com/smartor/common/ShiyiSmsUtil.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.java
@@ -1,66 +1,64 @@
-package com.smartor.common;
+package com.ruoyi.message.sms.provider.shiyi;
 
-import com.smartor.domain.ShiyiSmsRequest;
-import com.smartor.domain.ShiyiSmsResponse;
+import com.ruoyi.message.config.MessageProperties;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 import java.io.StringReader;
 import java.nio.charset.StandardCharsets;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
 /**
- * 鏉窞甯備竴 HIS 鏈嶅姟骞冲彴瀵规帴宸ュ叿绫汇��
+ * 鏉窞甯備竴 HIS 鏈嶅姟骞冲彴瀵规帴宸ュ叿绫伙紙鐭俊锛夈��
  * <p>
  * 鎸夈�奌IS 鏈嶅姟骞冲彴鎺ュ彛璇存槑鏂囨。 V1.1銆�3.1 鑺傜害瀹氾紝HIS 瀵瑰浠� WCF Web Service 褰㈠紡鍙戝竷锛�
  * 缁熶竴鍏ュ彛锛歿@code int RunService(string TradeType, string TradeMsg, ref string TradeOut)}锛�
  * 鍏朵腑 {@code TradeType} 鏍囪瘑涓氬姟缂栫爜锛寋@code TradeMsg} 涓� UTF-8 缂栫爜鐨� XML 鎶ユ枃銆�
- * 鏈伐鍏风被鐩墠瀹炵幇 5.2 鐭俊涓氬姟 (TradeType=FASONGDX)銆�
+ * 鏈被瀹炵幇 5.2 鐭俊涓氬姟 (TradeType=FASONGDX)銆�
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.smartor.common.ShiyiSmsUtil}銆傚樊寮傜偣锛�
+ * <ul>
+ *   <li>閰嶇疆鐢� {@code @Value("${his.service.defaultCaozuoydm:}")} 鏀逛负浠� {@link MessageProperties} 璇诲彇
+ *       锛堝墠缂� {@code message.sms.shiyi.*}锛夛紝鍘� key 涓嶅啀闇�瑕侊紱</li>
+ *   <li>鎺ュ彛鍦板潃鐢辩‖缂栫爜鏀逛负 {@code message.sms.shiyi.ws-url}锛岄粯璁ゅ�间笌鍘熺‖缂栫爜涓�鑷�
+ *       锛坽@code http://192.178.0.104:7790/MediInfoHis.svc}锛夈��</li>
+ * </ul>
  */
 @Slf4j
 @Component
 public class ShiyiSmsUtil {
 
-    /** 5.2 鐭俊涓氬姟 TradeType */
+    /**
+     * 5.2 鐭俊涓氬姟 TradeType
+     */
     public static final String TRADE_TYPE_FASONGDX = "FASONGDX";
 
-    /** WCF 鍛藉悕绌洪棿锛岄粯璁ら殢鏂囨。绀轰緥 */
-    private String namespace = "http://tempuri.org/";
+    /**
+     * WCF 鍛藉悕绌洪棿锛岄粯璁ら殢鏂囨。绀轰緥
+     */
+    private final String namespace = "http://tempuri.org/";
 
-    /** 榛樿鎿嶄綔鍛樹唬鐮� */
-    @Value("${his.service.defaultCaozuoydm:}")
-    private String defaultCaozuoydm;
-
-    /** 榛樿鎿嶄綔鍛樺鍚� */
-    @Value("${his.service.defaultCaozuoyxm:}")
-    private String defaultCaozuoyxm;
-
-    /** 榛樿绯荤粺鏍囪瘑 */
-    private String defaultXitongbs = "0";
-
-    /** 榛樿鍒嗛櫌浠g爜 */
-    private String defaultFenyuandm = "1";
-
-    /** 榛樿鏈烘瀯浠g爜 */
-    private String defaultJigoudm = "1";
+    private final MessageProperties properties;
 
     private final RestTemplate restTemplate = new RestTemplate();
+
+    public ShiyiSmsUtil(MessageProperties properties) {
+        this.properties = properties;
+    }
 
     /**
      * 鍙戦�佺煭淇� (FASONGDX)
@@ -88,13 +86,13 @@
     }
 
     /**
-     * 璋冪敤 甯備竴 WCF RunService 鎺ュ彛銆係OAP 1.1 鍩虹閴存潈鎸夋枃妗d笉瑕佹眰銆�
+     * 璋冪敤甯備竴 WCF RunService 鎺ュ彛銆係OAP 1.1 鍩虹閴存潈鎸夋枃妗d笉瑕佹眰銆�
      *
      * @return TradeOut 鎶ユ枃锛堟湇鍔$ ref 鍙傛暟锛�
      */
     public String invokeRunService(String tradeType, String tradeMsg) {
         String soapEnvelope = buildSoapEnvelope(tradeType, tradeMsg);
-        String hisServiceUrl = "http://192.178.0.104:7790/MediInfoHis.svc";
+        String hisServiceUrl = properties.getSms().getShiyi().getWsUrl();
 
         HttpHeaders headers = new HttpHeaders();
         headers.setContentType(new MediaType("text", "xml", StandardCharsets.UTF_8));
@@ -115,23 +113,24 @@
     }
 
     private void applyDefaults(ShiyiSmsRequest request) {
+        MessageProperties.ShiyiSms shiyi = properties.getSms().getShiyi();
         if (StringUtils.isBlank(request.getCaozuoydm())) {
-            request.setCaozuoydm(defaultCaozuoydm);
+            request.setCaozuoydm(shiyi.getDefaultCaozuoydm());
         }
         if (StringUtils.isBlank(request.getCaozuoyxm())) {
-            request.setCaozuoyxm(defaultCaozuoyxm);
+            request.setCaozuoyxm(shiyi.getDefaultCaozuoyxm());
         }
         if (StringUtils.isBlank(request.getCaozuorq())) {
             request.setCaozuorq(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
         }
         if (StringUtils.isBlank(request.getXitongbs())) {
-            request.setXitongbs(defaultXitongbs);
+            request.setXitongbs("0");
         }
         if (StringUtils.isBlank(request.getFenyuandm())) {
-            request.setFenyuandm(defaultFenyuandm);
+            request.setFenyuandm("1");
         }
         if (StringUtils.isBlank(request.getJigoudm())) {
-            request.setJigoudm(defaultJigoudm);
+            request.setJigoudm("1");
         }
         if (StringUtils.isBlank(request.getDuanxinlx())) {
             request.setDuanxinlx("0");
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.java
new file mode 100644
index 0000000..9caa7bf
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.java
@@ -0,0 +1,87 @@
+package com.ruoyi.message.sms.provider.sltd;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 鐪佺珛鍚屽痉鐭俊鍝嶅簲瑙f瀽銆�
+ * <p>
+ * 鐜扮姸锛堝悓涓�渚涘簲鍟嗐�佷袱濂楀啓娉曪紝蹇呴』閮藉吋瀹癸紝鍚﹀垯鏀逛簡灏辨槸鍥炲綊锛夛細
+ * <ul>
+ *   <li>{@code RyTask} / {@code RedisMqReceiver}锛氭寜 {@code result=0&description=鎴愬姛&faillist=} 瑙f瀽锛�
+ *       鍙� {@code result == "0"} 涓烘垚鍔燂紱</li>
+ *   <li>{@code SmsController./sms/send}锛氭寜 JSON 瑙f瀽 {@code result[0].status == "00000"} 涓烘垚鍔熴��</li>
+ * </ul>
+ * TODO 寰呯‘璁わ細浠ヤ笂涓ょ杩斿洖鍒ゅ畾鍒板簳鍝釜鎵嶆槸鐪佺珛鍚屽痉缃戝叧鐨勭湡瀹炶繑鍥炴牸寮忥紝闇�涓氬姟纭鍚庣粺涓�銆�
+ * 鏈В鏋愬櫒涓ょ閮藉吋瀹癸紝淇濊瘉杩佺Щ鍚庤涓轰笌绾夸笂涓�鑷淬��
+ */
+final class SltdResponseParser {
+
+    private SltdResponseParser() {
+    }
+
+    /**
+     * 瑙f瀽缁撴灉鍊硷紙鐢ㄤ簬鏃ュ織涓庢帓鏌ワ級
+     */
+    static String resultValue(String raw) {
+        if (StringUtils.isEmpty(raw)) {
+            return null;
+        }
+        String keyValue = readKeyValue(raw, "result");
+        if (keyValue != null) {
+            return keyValue;
+        }
+        return readJsonStatus(raw);
+    }
+
+    /**
+     * 鏄惁鍙戦�佹垚鍔燂細鍏煎 {@code result=0} 涓� {@code result[0].status=00000} 涓ょ鍒ゅ畾
+     */
+    static boolean isSuccess(String raw) {
+        if (StringUtils.isEmpty(raw)) {
+            return false;
+        }
+        String keyValue = readKeyValue(raw, "result");
+        if ("0".equals(keyValue)) {
+            return true;
+        }
+        return "00000".equals(readJsonStatus(raw));
+    }
+
+    /**
+     * 浠� {@code a=1&b=2} 褰㈠紡鐨勫搷搴旈噷鍙栧��
+     */
+    private static String readKeyValue(String raw, String key) {
+        String[] pairs = raw.split("&");
+        for (String pair : pairs) {
+            String[] kv = pair.split("=", 2);
+            if (key.equals(kv[0])) {
+                return kv.length > 1 ? kv[1] : null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 浠� JSON 鍝嶅簲閲屽彇 {@code result[0].status}
+     */
+    private static String readJsonStatus(String raw) {
+        try {
+            JSONObject root = JSON.parseObject(raw);
+            if (root == null) {
+                return null;
+            }
+            JSONArray result = root.getJSONArray("result");
+            if (result == null || result.isEmpty()) {
+                return null;
+            }
+            JSONObject first = result.getJSONObject(0);
+            return first == null ? null : first.getString("status");
+        } catch (Exception e) {
+            //涓嶆槸 JSON锛屽睘浜庢甯告儏鍐碉紙鍙栧喅浜庣綉鍏宠繑鍥炴牸寮忥級锛屼氦鐢� key-value 鍒嗘敮澶勭悊
+            return null;
+        }
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.java
new file mode 100644
index 0000000..0418824
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.java
@@ -0,0 +1,60 @@
+package com.ruoyi.message.sms.provider.sltd;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.provider.sltd.ws.MessageSend;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * 鐪佺珛鍚屽痉鐭俊鍙戦�佹柟锛坽@code sltd} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛欽AX-WS SOAP 缃戝叧锛坽@code i5GSend}锛夛紝鐭俊绫诲瀷鍥哄畾 {@code 6}锛堝唴瀹瑰惈閾炬帴鍜岀數璇濓級锛�
+ * 鎴愬姛鍒ゅ畾瑙� {@link SltdResponseParser}銆�
+ * 浠g爜鏉ユ簮锛歿@code RyTask.sltd 鍒嗘敮} + {@code RedisMqReceiver.sltd 鍒嗘敮}锛堣涓轰繚鎸佷笉鍙橈級銆�
+ */
+@Slf4j
+@Component
+public class SltdSmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key锛屼笌 {@code spring.profiles.active=sltd} 瀵瑰簲
+     */
+    public static final String KEY = "sltd";
+
+    /**
+     * 鐭俊绫诲瀷锛氬唴瀹规湁閾炬帴鍜岀數璇�
+     */
+    private static final String MESSAGE_TYPE_SMS = "6";
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "鐪佺珛鍚屽痉鐭俊锛圫OAP i5GSend锛岀被鍨�6锛�";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) {
+        String raw = MessageSend.sendMsg(
+                request.getContent(),
+                MESSAGE_TYPE_SMS,
+                request.getPhone(),
+                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
+        log.info("銆恵}銆戠渷绔嬪悓寰风煭淇″彂閫佽繑鍥烇細{}", KEY, raw);
+
+        String code = SltdResponseParser.resultValue(raw);
+        if (SltdResponseParser.isSuccess(raw)) {
+            return SendResult.success(KEY, MessageChannel.SMS, raw).withCode(code);
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", raw).withCode(code);
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/Hello.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/Hello.java
similarity index 92%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/Hello.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/Hello.java
index 230c90a..251a383 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/Hello.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/Hello.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/HelloResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/HelloResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.java
index d575573..5b22c9e 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/HelloResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReply.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.java
similarity index 98%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReply.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.java
index 52636f3..c25647f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReply.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReplyResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReplyResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.java
index 809aa02..5c0f955 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReplyResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReport.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.java
similarity index 92%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReport.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.java
index 1c42ba2..44c1779 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReport.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReportResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReportResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.java
index 198f3bc..2ec2175 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GReportResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSearchNumber.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.java
similarity index 92%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSearchNumber.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.java
index 113ede0..6c751c2 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSearchNumber.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSearchNumberResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSearchNumberResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.java
index 24eb832..b483c5e 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSearchNumberResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSend.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.java
similarity index 98%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSend.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.java
index 39fea0f..5d371d7 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSend.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSendResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSendResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.java
index 21eedf3..44f0644 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/I5GSendResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.java
new file mode 100644
index 0000000..a9b513b
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.java
@@ -0,0 +1,71 @@
+package com.ruoyi.message.sms.provider.sltd.ws;
+
+import com.ruoyi.common.utils.uuid.UUID;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 鐪佺珛鍚屽痉淇℃伅鍙戦�佹帴鍙c��
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.ruoyi.common.dx.MessageSend}锛岄殢銆岀煭淇″彂閫佹柟銆嶄竴璧锋敹鍙e埌
+ * {@code ruoyi-message} 妯″潡銆傛柟娉曠鍚嶄笌琛屼负淇濇寔涓嶅彉锛屼究浜庤皟鐢ㄦ柟闆舵敼鍔ㄥ垏鎹€��
+ */
+@Slf4j
+public class MessageSend {
+
+    private static final Logger logger = LoggerFactory.getLogger(MessageSend.class);
+
+    /**
+     * 鍘傚璁稿彲鍙凤紙纭紪鐮侊級銆�
+     * <p>
+     * TODO 寰呯‘璁わ細鍘熷疄鐜版妸鍘傚璁稿彲鍙峰啓姝诲湪浠g爜閲岋紝鏈蛋閰嶇疆锛屾澶勪繚鎸佸師鍊间笉鍙樸��
+     */
+    private static final String SERVICE_NUMBER = "202508291634227086";
+
+    /**
+     * 鐭俊妯℃澘璁稿彲鍙凤紙鍐呭甯﹂摼鎺ュ拰鐢佃瘽锛�
+     */
+    private static final String SMS_TEMPLATE_NUMBER = "T202508291635259440";
+
+    /**
+     * 閽夐拤娑堟伅妯℃澘璁稿彲鍙�
+     */
+    private static final String DINGTALK_TEMPLATE_NUMBER = "T202607211306131891";
+
+    /**
+     * 鐪佺珛鍚屽痉淇℃伅鍙戦��
+     *
+     * @param sMessageContent 鐭俊鍐呭
+     * @param sMessageType    鐭俊绫诲瀷 1=楠岃瘉鐮併��2=閫氱煡銆�3=骞垮憡 6=鍐呭鏈夐摼鎺ュ拰鐢佃瘽锛�7=閽夐拤娑堟伅
+     * @param sUserNumber     鎵嬫満鍙风爜
+     * @param sScheduleTime   棰勭害鍙戦�佹椂闂�
+     * @return 绗笁鏂瑰師濮嬪搷搴�
+     */
+    public static String sendMsg(String sMessageContent, String sMessageType, String sUserNumber, String sScheduleTime) {
+        log.info("--sMessageContent 鐨勫�间负锛歿}   ,--sMessageType 鐨勫�间负锛歿},   --sUserNumber 鐨勫�间负锛歿},   --sScheduleTime 鐨勫�间负:{}", sMessageContent, sMessageType, sUserNumber, sScheduleTime);
+
+        SmsService service = new SmsService();
+        SmsServiceSoap soap = service.getSmsServiceSoap();
+        String result = null;
+
+        try {
+            if ("6".equals(sMessageType)) {
+                result = soap.i5GSend(SERVICE_NUMBER, SMS_TEMPLATE_NUMBER, UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
+                log.info("----鐭俊杩斿洖鐨勬暟鎹负锛歿},    ----sMessageContent 鐨勫�间负:{}", result, UUID.randomUUID().toString());
+            } else if ("7".equals(sMessageType)) {
+                result = soap.i5GSend(SERVICE_NUMBER, DINGTALK_TEMPLATE_NUMBER,
+                        UUID.randomUUID().toString(), sMessageContent, sMessageType, sUserNumber, sScheduleTime);
+                log.info("----閽夐拤杩斿洖鐨勫師濮嬫暟鎹负锛歿}", result);
+            } else {
+                log.warn("涓嶆敮鎸佺殑鐭俊绫诲瀷锛歿}", sMessageType);
+            }
+        } catch (Exception e) {
+            //鍘熷疄鐜颁负 e.getCause().getMessage()锛屽綋 cause 涓� null 鏃朵細鎶� NPE 鎺╃洊鐪熷疄寮傚父锛岃繖閲屽仛闃插尽
+            String cause = e.getCause() == null ? e.getMessage() : e.getCause().getMessage();
+            logger.error("瀹屾暣閿欒淇℃伅锛歿}", cause);
+        }
+
+        return result;
+    }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/ObjectFactory.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.java
similarity index 95%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/ObjectFactory.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.java
index 4672823..e28c7a4 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/ObjectFactory.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlRegistry;
 
@@ -7,7 +7,7 @@
 /**
  * This object contains factory methods for each 
  * Java content interface and Java element interface 
- * generated in the com.ruoyi.common.dx package. 
+ * generated in the com.ruoyi.message.sms.provider.sltd.ws package. 
  * <p>An ObjectFactory allows you to programatically 
  * construct new instances of the Java representation 
  * for XML content. The Java representation of XML 
@@ -23,7 +23,7 @@
 
 
     /**
-     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.ruoyi.common.dx
+     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.ruoyi.message.sms.provider.sltd.ws
      * 
      */
     public ObjectFactory() {
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetNumber.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.java
similarity index 92%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetNumber.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.java
index b80911d..d8d3d40 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetNumber.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetNumberResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetNumberResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.java
index 4986791..788384f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetNumberResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetTemplateList.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetTemplateList.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.java
index 2f04bdd..55acd6e 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetTemplateList.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetTemplateListResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetTemplateListResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.java
index 18a963b..475350c 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetTemplateListResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetUserList.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetUserList.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.java
index d442868..43eac06 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetUserList.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetUserListResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetUserListResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.java
index 995f8fc..58fff7e 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSGetUserListResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSSaveContent.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.java
similarity index 98%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSSaveContent.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.java
index f7c0d75..a479f1f 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSSaveContent.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSSaveContentResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSSaveContentResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.java
index 32897ea..54ae174 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSSaveContentResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerify.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.java
similarity index 97%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerify.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.java
index 7bd805f..962dd50 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerify.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyPrivate.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyPrivate.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.java
index 5b29027..0d06fca 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyPrivate.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyPrivateResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyPrivateResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.java
index 6ac69b2..e0b661d 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyPrivateResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyResponse.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.java
similarity index 96%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyResponse.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.java
index 8f7f34e..c74a0dd 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SMSVerifyResponse.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SmsService.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsService.java
similarity index 97%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SmsService.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsService.java
index cf89da0..91632c3 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SmsService.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsService.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import java.net.MalformedURLException;
 import java.net.URL;
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SmsServiceSoap.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.java
similarity index 80%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/SmsServiceSoap.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.java
index 106029a..6628c69 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/SmsServiceSoap.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.java
@@ -1,5 +1,5 @@
 
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
 
 import javax.jws.WebMethod;
 import javax.jws.WebParam;
@@ -30,8 +30,8 @@
      */
     @WebMethod(operationName = "Hello", action = "http://tempuri.org/Hello")
     @WebResult(name = "HelloResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "Hello", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.Hello")
-    @ResponseWrapper(localName = "HelloResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.HelloResponse")
+    @RequestWrapper(localName = "Hello", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.Hello")
+    @ResponseWrapper(localName = "HelloResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.HelloResponse")
     public String hello();
 
     /**
@@ -43,8 +43,8 @@
      */
     @WebMethod(operationName = "SMSVerifyPrivate", action = "http://tempuri.org/SMSVerifyPrivate")
     @WebResult(name = "SMSVerifyPrivateResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "SMSVerifyPrivate", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSVerifyPrivate")
-    @ResponseWrapper(localName = "SMSVerifyPrivateResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSVerifyPrivateResponse")
+    @RequestWrapper(localName = "SMSVerifyPrivate", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSVerifyPrivate")
+    @ResponseWrapper(localName = "SMSVerifyPrivateResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSVerifyPrivateResponse")
     public String smsVerifyPrivate(
             @WebParam(name = "sServerNumber", targetNamespace = "http://tempuri.org/")
             String sServerNumber);
@@ -59,8 +59,8 @@
      */
     @WebMethod(operationName = "SMSVerify", action = "http://tempuri.org/SMSVerify")
     @WebResult(name = "SMSVerifyResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "SMSVerify", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSVerify")
-    @ResponseWrapper(localName = "SMSVerifyResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSVerifyResponse")
+    @RequestWrapper(localName = "SMSVerify", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSVerify")
+    @ResponseWrapper(localName = "SMSVerifyResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSVerifyResponse")
     public String smsVerify(
             @WebParam(name = "sServerNumber", targetNamespace = "http://tempuri.org/")
             String sServerNumber,
@@ -76,8 +76,8 @@
      */
     @WebMethod(operationName = "SMSGetUserList", action = "http://tempuri.org/SMSGetUserList")
     @WebResult(name = "SMSGetUserListResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "SMSGetUserList", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSGetUserList")
-    @ResponseWrapper(localName = "SMSGetUserListResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSGetUserListResponse")
+    @RequestWrapper(localName = "SMSGetUserList", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSGetUserList")
+    @ResponseWrapper(localName = "SMSGetUserListResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSGetUserListResponse")
     public String smsGetUserList(
             @WebParam(name = "sUserName", targetNamespace = "http://tempuri.org/")
             String sUserName);
@@ -91,8 +91,8 @@
      */
     @WebMethod(operationName = "SMSGetTemplateList", action = "http://tempuri.org/SMSGetTemplateList")
     @WebResult(name = "SMSGetTemplateListResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "SMSGetTemplateList", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSGetTemplateList")
-    @ResponseWrapper(localName = "SMSGetTemplateListResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSGetTemplateListResponse")
+    @RequestWrapper(localName = "SMSGetTemplateList", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSGetTemplateList")
+    @ResponseWrapper(localName = "SMSGetTemplateListResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSGetTemplateListResponse")
     public String smsGetTemplateList(
             @WebParam(name = "sUserName", targetNamespace = "http://tempuri.org/")
             String sUserName);
@@ -105,8 +105,8 @@
      */
     @WebMethod(operationName = "SMSGetNumber", action = "http://tempuri.org/SMSGetNumber")
     @WebResult(name = "SMSGetNumberResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "SMSGetNumber", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSGetNumber")
-    @ResponseWrapper(localName = "SMSGetNumberResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSGetNumberResponse")
+    @RequestWrapper(localName = "SMSGetNumber", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSGetNumber")
+    @ResponseWrapper(localName = "SMSGetNumberResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSGetNumberResponse")
     public String smsGetNumber();
 
     /**
@@ -128,8 +128,8 @@
      */
     @WebMethod(operationName = "SMSSaveContent", action = "http://tempuri.org/SMSSaveContent")
     @WebResult(name = "SMSSaveContentResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "SMSSaveContent", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSSaveContent")
-    @ResponseWrapper(localName = "SMSSaveContentResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.SMSSaveContentResponse")
+    @RequestWrapper(localName = "SMSSaveContent", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSSaveContent")
+    @ResponseWrapper(localName = "SMSSaveContentResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.SMSSaveContentResponse")
     public int smsSaveContent(
             @WebParam(name = "sSUseq", targetNamespace = "http://tempuri.org/")
             String sSUseq,
@@ -169,8 +169,8 @@
      */
     @WebMethod(action = "http://tempuri.org/i5GSend")
     @WebResult(name = "i5GSendResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "i5GSend", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GSend")
-    @ResponseWrapper(localName = "i5GSendResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GSendResponse")
+    @RequestWrapper(localName = "i5GSend", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GSend")
+    @ResponseWrapper(localName = "i5GSendResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GSendResponse")
     public String i5GSend(
             @WebParam(name = "sServerNumber", targetNamespace = "http://tempuri.org/")
             String sServerNumber,
@@ -195,8 +195,8 @@
      */
     @WebMethod(action = "http://tempuri.org/i5GReport")
     @WebResult(name = "i5GReportResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "i5GReport", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GReport")
-    @ResponseWrapper(localName = "i5GReportResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GReportResponse")
+    @RequestWrapper(localName = "i5GReport", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GReport")
+    @ResponseWrapper(localName = "i5GReportResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GReportResponse")
     public String i5GReport();
 
     /**
@@ -207,8 +207,8 @@
      */
     @WebMethod(action = "http://tempuri.org/i5GSearchNumber")
     @WebResult(name = "i5GSearchNumberResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "i5GSearchNumber", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GSearchNumber")
-    @ResponseWrapper(localName = "i5GSearchNumberResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GSearchNumberResponse")
+    @RequestWrapper(localName = "i5GSearchNumber", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GSearchNumber")
+    @ResponseWrapper(localName = "i5GSearchNumberResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GSearchNumberResponse")
     public String i5GSearchNumber();
 
     /**
@@ -223,8 +223,8 @@
      */
     @WebMethod(action = "http://tempuri.org/i5GReply")
     @WebResult(name = "i5GReplyResult", targetNamespace = "http://tempuri.org/")
-    @RequestWrapper(localName = "i5GReply", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GReply")
-    @ResponseWrapper(localName = "i5GReplyResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.common.dx.I5GReplyResponse")
+    @RequestWrapper(localName = "i5GReply", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GReply")
+    @ResponseWrapper(localName = "i5GReplyResponse", targetNamespace = "http://tempuri.org/", className = "com.ruoyi.message.sms.provider.sltd.ws.I5GReplyResponse")
     public String i5GReply(
             @WebParam(name = "sServerNumber", targetNamespace = "http://tempuri.org/")
             String sServerNumber,
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/dx/package-info.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/package-info.java
similarity index 74%
rename from ruoyi-common/src/main/java/com/ruoyi/common/dx/package-info.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/package-info.java
index 116c7ec..1bcf698 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/dx/package-info.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/sltd/ws/package-info.java
@@ -1,2 +1,2 @@
 @javax.xml.bind.annotation.XmlSchema(namespace = "http://tempuri.org/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
-package com.ruoyi.common.dx;
+package com.ruoyi.message.sms.provider.sltd.ws;
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.java
new file mode 100644
index 0000000..01ed3ef
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.java
@@ -0,0 +1,144 @@
+package com.ruoyi.message.sms.provider.xh;
+
+import com.ruoyi.common.utils.HttpUtil;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.config.MessageProperties;
+import com.ruoyi.message.config.XhsmsConfig;
+import com.ruoyi.message.config.RootMessageProperties;
+import com.ruoyi.message.sms.AbstractSmsSender;
+import com.ruoyi.message.sms.SmsSendRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.net.URLEncoder;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 鏂板崕鐭俊鍙戦�佹柟锛坽@code xh} 閫氶亾锛岄�氱敤鐭俊缃戝叧锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛欻TTP POST 琛ㄥ崟 {@code action/account/password/mobile/content/extno/rt}锛屾棤绛惧悕銆�
+ * <p>
+ * 鈿狅笍 鐜版湁涓変釜鍏ュ彛瀵瑰悓涓�涓綉鍏崇殑璋冪敤鏂瑰紡骞朵笉涓�鑷达紝涓斿叾涓袱涓槸鍧忕殑銆備负婊¤冻銆屾寜绔欑偣鍘熸牱灏佽銆�
+ * 涓嶆敼绾夸笂琛屼负銆嶇殑瑕佹眰锛岃繖閲屾妸涓夌妯″紡閮戒繚鐣欎负鐙珛鏂规硶锛岀敱璋冪敤鏂规寜鍘熺珯鐐归�夋嫨锛�
+ * <ul>
+ *   <li>{@link #sendJsonLegacy} 鈥斺�� 绛変环 {@code RyTask}锛氭嫾濂借〃鍗曞弬鏁板嵈鍙戦�� {@code new Gson().toJson(req)}
+ *       锛坽@code req} 鏄┖ map锛屽疄闄呭彂鍑� {@code {}}锛夛紝涓旀妸 {@code Boolean} 褰� {@code String} 杩斿洖鍊硷紝
+ *       蹇呯劧瑙﹀彂 NPE 琚紓甯稿垎鏀悶鎺夈�傜粨鏋滐細**鏂板崕绔欑偣闀挎湡浠诲姟鐭俊瀹為檯鍙戜笉鍑哄幓**锛�</li>
+ *   <li>{@link #sendForm} 鈥斺�� 绛変环 {@code RedisMqReceiver}锛氬彂閫� URL 缂栫爜鍚庣殑琛ㄥ崟瀛楃涓诧紙姝g‘锛夛紝
+ *       浣嗗師瀹炵幇蹇界暐浜嗚繑鍥炲�硷紝浠g爜閲屽浐瀹氭寜鎴愬姛澶勭悊锛�</li>
+ *   <li>{@link #sendJson} 鈥斺�� 绛変环 {@code ServiceSubtaskServiceImpl.smsSubTask} / {@code SmsController}锛�
+ *       鍙戦�� {@code Gson.toJson(map)} 鐨� JSON銆�</li>
+ * </ul>
+ * TODO 寰呯‘璁わ細浠ヤ笂涓夌鍐欐硶鍝竴绉嶆墠鏄柊鍗庣綉鍏崇湡姝f帴鍙楃殑鎶ユ枃鏍煎紡锛堝緢鍙兘鏄� {@link #sendForm}锛夛紝
+ * 纭鍚庡簲缁熶竴涓轰竴绉嶅苟鍒犻櫎鍏朵綑涓ょ銆�
+ */
+@Slf4j
+@Component
+public class XinHuaSmsSender extends AbstractSmsSender {
+
+    /**
+     * 娓犻亾 key锛屼笌 {@code spring.profiles.active=xh} 瀵瑰簲
+     */
+    public static final String KEY = "xh";
+
+    private final MessageProperties properties;
+
+    public XinHuaSmsSender(MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "鏂板崕鐭俊锛堥�氱敤缃戝叧锛岃〃鍗�/JSON 涓ょ鎶ユ枃锛�";
+    }
+
+    @Override
+    protected SendResult doSend(SmsSendRequest request) {
+        //榛樿鎸� RedisMqReceiver 鐨勶紙姝g‘锛夎〃鍗曟ā寮忓彂閫�
+        return sendForm(request);
+    }
+
+    /**
+     * 妯″紡涓�锛氳〃鍗曞瓧绗︿覆锛堢瓑浠� {@code RedisMqReceiver}锛屾帹鑽愶級
+     */
+    public SendResult sendForm(SmsSendRequest request) {
+        XhsmsConfig cfg = properties.getSms().getXhsms();
+        String encodedParams = buildEncodedParams(request, cfg);
+        log.info("銆恵}銆戞柊鍗庣煭淇″彂閫侊紙琛ㄥ崟锛夛紝鍦板潃锛歿}锛屽弬鏁帮細{}", KEY, cfg.getPath(), encodedParams);
+        HttpUtils.sendPost(cfg.getPath(), encodedParams);
+        //涓庣嚎涓婅涓轰竴鑷达細鍘熷疄鐜版湭浣跨敤杩斿洖鍊硷紝鍥哄畾鎸夋垚鍔熷鐞�
+        return SendResult.success(KEY, MessageChannel.SMS, encodedParams);
+    }
+
+    /**
+     * 妯″紡浜岋細JSON 鎶ユ枃锛堢瓑浠� {@code smsSubTask} / {@code SmsController}锛�
+     */
+    public SendResult sendJson(SmsSendRequest request) {
+        XhsmsConfig cfg = properties.getSms().getXhsms();
+        Map<String, String> params = buildParams(request, cfg);
+        String json = com.alibaba.fastjson.JSON.toJSONString(params);
+        log.info("銆恵}銆戞柊鍗庣煭淇″彂閫侊紙JSON锛夛紝鍦板潃锛歿}锛屽弬鏁帮細{}", KEY, cfg.getPath(), json);
+        Boolean ok = HttpUtil.postJsonRequest(cfg.getPath(), json);
+        if (Boolean.TRUE.equals(ok)) {
+            return SendResult.success(KEY, MessageChannel.SMS, json);
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", json);
+    }
+
+    /**
+     * 妯″紡涓夛細鍏煎 {@code RyTask} 鐨勬棫瀹炵幇锛堝彂閫佺┖ JSON锛屽繀鐒跺け璐ワ級銆�
+     * <p>
+     * 淇濈暀姝ゆ柟娉曟槸涓轰簡璁� {@code RyTask} 鐨勬敼閫犲彲浠ュ仛鍒般�岃涓轰竴瀛椾笉宸�嶏紱纭缃戝叧鏍煎紡鍚庡簲鍒犻櫎銆�
+     */
+    public SendResult sendJsonLegacy(SmsSendRequest request) {
+        XhsmsConfig cfg = properties.getSms().getXhsms();
+        //鍘熷疄鐜帮細Map<String,String> req = new HashMap<>(); ...(HttpUtils.sendPost(xhsmsPath, new Gson().toJson(req));
+        //        Gson 搴忓垪鍖栫┖ map 鐨勭粨鏋滃嵆 "{}"
+        String emptyJson = "{}";
+        log.info("銆恵}銆戞柊鍗庣煭淇″彂閫侊紙RyTask 鏃у疄鐜帮紝鍙戦�佺┖鎶ユ枃锛夛紝鍦板潃锛歿}", KEY, cfg.getPath());
+        Boolean result = HttpUtils.sendPost(cfg.getPath(), emptyJson);
+        if (Boolean.TRUE.equals(result)) {
+            return SendResult.success(KEY, MessageChannel.SMS, emptyJson);
+        }
+        return SendResult.fail(KEY, MessageChannel.SMS, "鐭俊鍙戦�佸け璐�", emptyJson);
+    }
+
+    private Map<String, String> buildParams(SmsSendRequest request, XhsmsConfig cfg) {
+        Map<String, String> params = new LinkedHashMap<>();
+        params.put("action", "send");
+        params.put("account", cfg.getAccount());
+        params.put("password", cfg.getPwd());
+        params.put("mobile", request.getPhone());
+        params.put("content", request.getContent());
+        params.put("extno", cfg.getExtno());
+        params.put("rt", "json");
+        return params;
+    }
+
+    private String buildEncodedParams(SmsSendRequest request, XhsmsConfig cfg) {
+        StringBuilder encodedParams = new StringBuilder();
+        for (Map.Entry<String, String> entry : buildParams(request, cfg).entrySet()) {
+            if (encodedParams.length() > 0) {
+                encodedParams.append("&");
+            }
+            encodedParams.append(encode(entry.getKey())).append("=").append(encode(entry.getValue()));
+        }
+        return encodedParams.toString();
+    }
+
+    private String encode(String value) {
+        try {
+            return URLEncoder.encode(value == null ? "" : value, "UTF-8");
+        } catch (Exception e) {
+            return value;
+        }
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfig.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfig.java
new file mode 100644
index 0000000..6a3a2a0
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfig.java
@@ -0,0 +1,86 @@
+package com.ruoyi.message.wechat;
+
+/**
+ * 寰俊鍏紬鍙锋満鏋勭骇閰嶇疆锛坅ppid / appSecret / 缃戝叧鍦板潃锛夈��
+ * <p>
+ * 鐜扮姸锛氳繖浜涘�肩‖缂栫爜鍦� {@code com.ruoyi.common.enums.WxGZHEnum} 鏋氫妇閲岋紙涓芥按甯備腑鍖婚櫌銆佹櫙瀹併�佹箹婊ㄣ�佸惔灞憋級锛�
+ * 鐢� {@code WxGZHEnum.getDescByCode(orgid)} 杩斿洖涓�涓寜鍥哄畾椤哄簭鎺掑垪鐨� List锛�
+ * 璋冪敤鏂归潬涓嬫爣 {@code get(1)/get(2)/get(3)} 鍙栧�� 鈥斺�� 杩欐槸寰堣剢鐨勫啓娉曪紙涓�鏃︽煇涓満鏋勭己 appid锛�
+ * 涓嬫爣灏变細鏁翠綋閿欎綅锛涙櫙瀹佸氨鏄洜涓� appid 涓虹┖瀵艰嚧 {@code size()<4} 琚烦杩囷級銆�
+ * <p>
+ * 鏈被鎶婁笅鏍囪涔夋樉寮忓寲锛岄伩鍏嶇户缁敤 List 涓嬫爣浼犻�掋��
+ */
+public class WechatMpConfig {
+
+    /**
+     * 鏈烘瀯ID
+     */
+    private String orgid;
+
+    /**
+     * 鍏紬鍙� AppID
+     */
+    private String appid;
+
+    /**
+     * 鍏紬鍙� AppSecret锛堝弬涓庣鍚嶏級
+     */
+    private String appSecret;
+
+    /**
+     * 鍏紬鍙风綉鍏冲湴鍧�
+     */
+    private String address;
+
+    /**
+     * 鏄惁閰嶇疆瀹屾暣锛坅ppid/appSecret/address 閮戒笉涓虹┖锛�
+     */
+    public boolean isComplete() {
+        return isNotEmpty(appid) && isNotEmpty(appSecret) && isNotEmpty(address);
+    }
+
+    private static boolean isNotEmpty(String value) {
+        return value != null && !value.trim().isEmpty();
+    }
+
+    public String getOrgid() {
+        return orgid;
+    }
+
+    public void setOrgid(String orgid) {
+        this.orgid = orgid;
+    }
+
+    public String getAppid() {
+        return appid;
+    }
+
+    public void setAppid(String appid) {
+        this.appid = appid;
+    }
+
+    public String getAppSecret() {
+        return appSecret;
+    }
+
+    public void setAppSecret(String appSecret) {
+        this.appSecret = appSecret;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    @Override
+    public String toString() {
+        return "WechatMpConfig{orgid='" + orgid + '\''
+                + ", appid='" + appid + '\''
+                + ", appSecret='" + (appSecret == null ? null : "***") + '\''
+                + ", address='" + address + '\''
+                + '}';
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfigProvider.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfigProvider.java
new file mode 100644
index 0000000..80deea8
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatMpConfigProvider.java
@@ -0,0 +1,19 @@
+package com.ruoyi.message.wechat;
+
+/**
+ * 寰俊鍏紬鍙锋満鏋勭骇閰嶇疆鎻愪緵鏂癸紙鎵╁睍鐐� SPI锛夈��
+ * <p>
+ * 鐢变笟鍔℃ā鍧楀疄鐜帮紙褰撳墠搴斿鎵樼粰 {@code com.ruoyi.common.enums.WxGZHEnum} 浠ヤ繚鎸侀厤缃簮涓嶅彉锛�
+ * 鍚庣画鍙敼涓烘暟鎹簱/閰嶇疆涓績锛夈�傝嫢瀹瑰櫒涓病鏈夊疄鐜帮紝鍒欒涓恒�岃鏈烘瀯娌℃湁閰嶇疆鍏紬鍙枫�嶏紝
+ * 涓庣嚎涓� {@code wxqqxx} 涓虹┖鏃剁殑澶辫触琛ㄧ幇涓�鑷淬��
+ */
+public interface WechatMpConfigProvider {
+
+    /**
+     * 鎸夋満鏋処D鏌ヨ鍏紬鍙烽厤缃�
+     *
+     * @param orgid 鏈烘瀯ID
+     * @return 閰嶇疆锛涙湭閰嶇疆杩斿洖 {@code null}
+     */
+    WechatMpConfig getConfig(String orgid);
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSendRequest.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSendRequest.java
new file mode 100644
index 0000000..8bc9e27
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSendRequest.java
@@ -0,0 +1,97 @@
+package com.ruoyi.message.wechat;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 寰俊鍏紬鍙峰彂閫佽姹傦紙涓庡叿浣撳彂閫佹柟鏃犲叧鐨勭粺涓�鍏ュ弬锛夈��
+ * <p>
+ * 鍚勫尰闄㈠叕浼楀彿鐨勫叆鍙傚樊寮傚緢澶э紙甯備竴鍙 鎵嬫満鍙�+韬唤璇�+閾炬帴锛屾柊鍗庤 鎮h�匢D+濮撳悕+appid+绛惧悕锛夛紝
+ * 宸紓瀛楁閫氳繃 {@link #extras} 閫忎紶銆�
+ */
+@Data
+public class WechatSendRequest implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎵嬫満鍙�
+     */
+    private String phone;
+
+    /**
+     * 韬唤璇佸彿锛堝競涓�銆佹柊鍗庨兘瑕侊級
+     */
+    private String idCard;
+
+    /**
+     * 澶栭摼鍦板潃锛堢偣鍑绘秷鎭悗璺宠浆锛�
+     */
+    private String url;
+
+    /**
+     * 鏍囬 / 浠诲姟鍚嶇О
+     */
+    private String title;
+
+    /**
+     * 鍐呭 / 浠诲姟鎻忚堪
+     */
+    private String content;
+
+    /**
+     * 鏈烘瀯ID
+     */
+    private String orgid;
+
+    /**
+     * HIS 渚ф偅鑰匢D锛堟柊鍗庤姹傞潪绌猴級
+     */
+    private String patidHis;
+
+    /**
+     * 鎮h�呭鍚�
+     */
+    private String patientName;
+
+    /**
+     * openid锛堝井淇″叕浼楀彿 SDK 閫氶亾浣跨敤锛�
+     */
+    private String openid;
+
+    /**
+     * 妯℃澘ID锛堝井淇″叕浼楀彿 SDK 妯℃澘娑堟伅閫氶亾浣跨敤锛�
+     */
+    private String templateId;
+
+    /**
+     * 鏄惁鍏抽棴 Gson 鐨� HTML 杞箟锛堟柊鍗庡叕浼楀彿绔欑偣闂村瓨鍦ㄥ樊寮傦紝瑙� {@code XinHuaMpApi.sendMessage}锛�
+     */
+    private boolean disableHtmlEscaping;
+
+    /**
+     * 鎵╁睍鍙傛暟
+     */
+    private Map<String, Object> extras;
+
+    /**
+     * 杩藉姞涓�涓墿灞曞弬鏁�
+     */
+    public WechatSendRequest putExtra(String key, Object value) {
+        if (this.extras == null) {
+            this.extras = new LinkedHashMap<>();
+        }
+        this.extras.put(key, value);
+        return this;
+    }
+
+    /**
+     * 璇诲彇鎵╁睍鍙傛暟
+     */
+    public Object getExtra(String key) {
+        return this.extras == null ? null : this.extras.get(key);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSender.java
new file mode 100644
index 0000000..6363162
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSender.java
@@ -0,0 +1,32 @@
+package com.ruoyi.message.wechat;
+
+import com.ruoyi.message.SendResult;
+
+/**
+ * 寰俊鍏紬鍙峰彂閫佹柟锛堜竴涓笭閬撲竴涓疄鐜帮級銆�
+ * <p>
+ * 鐜扮姸锛氬競涓�锛坰msUtils.sendChat锛夊拰鏂板崕锛坓etWXCode锛夎蛋鐨勬槸涓ゅ瀹屽叏涓嶅悓鐨勭涓夋柟缃戝叧锛�
+ * 杩斿洖浣撳垽瀹氫篃涓嶄竴鏍凤紙甯備竴鐪� {@code success==1}锛屾柊鍗庣湅 {@code succ==true}锛夛紝鍥犳鍒嗗紑瀹炵幇銆�
+ */
+public interface WechatSender {
+
+    /**
+     * 鍙戦�佹柟鍞竴 key
+     */
+    String key();
+
+    /**
+     * 鍙戦�佸叕浼楀彿娑堟伅
+     *
+     * @param request 缁熶竴鍏ュ弬
+     * @return 缁熶竴缁撴灉锛屼笉鎶涘紓甯�
+     */
+    SendResult send(WechatSendRequest request);
+
+    /**
+     * 鍙戦�佹柟璇存槑锛岀敤浜庢棩蹇椾笌鎺掓煡
+     */
+    default String description() {
+        return key();
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSenderFactory.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSenderFactory.java
new file mode 100644
index 0000000..86b39ce
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/WechatSenderFactory.java
@@ -0,0 +1,78 @@
+package com.ruoyi.message.wechat;
+
+import com.ruoyi.message.SendException;
+import com.ruoyi.message.SendResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * 寰俊鍏紬鍙峰彂閫佹柟宸ュ巶锛氭寜 key 璺敱鍒颁竴涓叿浣撳疄鐜般��
+ * <p>
+ * 娉ㄦ剰锛氬叕浼楀彿閫氶亾鐨� key 涓庣煭淇¢�氶亾鐨� key 鍙互鍚屽悕锛堜緥濡� {@code hzszlyy} 鏃㈡湁鐭俊鍙戦�佹柟
+ * 涔熸湁鍏紬鍙峰彂閫佹柟锛夛紝鍥犳涓や釜宸ュ巶鍚勮嚜缁存姢鑷繁鐨勬敞鍐岃〃锛屼簰涓嶅共鎵般��
+ */
+@Slf4j
+@Component
+public class WechatSenderFactory {
+
+    private final Map<String, WechatSender> senders = new LinkedHashMap<>();
+
+    public WechatSenderFactory(List<WechatSender> senderList) {
+        for (WechatSender sender : senderList) {
+            WechatSender exists = senders.put(sender.key(), sender);
+            if (exists != null) {
+                throw new IllegalStateException("鍏紬鍙峰彂閫佹柟 key 閲嶅锛�" + sender.key()
+                        + "锛屽啿绐佸疄鐜帮細" + exists.getClass().getName() + " 涓� " + sender.getClass().getName());
+            }
+        }
+        log.info("銆怶echatSenderFactory銆戝凡娉ㄥ唽鍏紬鍙峰彂閫佹柟锛歿}", senders.keySet());
+    }
+
+    /**
+     * 鎸� key 鑾峰彇鍙戦�佹柟
+     *
+     * @param key 娓犻亾 key锛堝嵆 {@code spring.profiles.active} 鍙栧�硷級
+     * @throws SendException 鎵句笉鍒板搴斿疄鐜版椂鎶涘嚭
+     */
+    public WechatSender get(String key) {
+        WechatSender sender = key == null ? null : senders.get(key);
+        if (sender == null) {
+            throw new SendException("鏈壘鍒板叕浼楀彿鍙戦�佹柟锛宬ey=" + key + "锛屽凡娉ㄥ唽锛�" + senders.keySet());
+        }
+        return sender;
+    }
+
+    /**
+     * 鎸� key 鑾峰彇鍙戦�佹柟锛屾壘涓嶅埌杩斿洖 {@code null}
+     */
+    public WechatSender getOrNull(String key) {
+        return key == null ? null : senders.get(key);
+    }
+
+    /**
+     * 鎸� key 鍙戦�佸叕浼楀彿娑堟伅
+     */
+    public SendResult send(String key, WechatSendRequest request) {
+        return get(key).send(request);
+    }
+
+    /**
+     * 鍒ゆ柇鏄惁瀛樺湪璇� key 鐨勫彂閫佹柟
+     */
+    public boolean supports(String key) {
+        return getOrNull(key) != null;
+    }
+
+    /**
+     * 宸叉敞鍐岀殑娓犻亾 key
+     */
+    public Set<String> keys() {
+        return new TreeSet<>(senders.keySet());
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.java
new file mode 100644
index 0000000..12661b3
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.java
@@ -0,0 +1,56 @@
+package com.ruoyi.message.wechat.provider.hzszlyy;
+
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.message.config.MessageProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鏉窞甯備竴寰俊鍏紬鍙� API銆�
+ * <p>
+ * 瀵规帴鐗瑰緛锛欸ET 璇锋眰 {@code /sfjk/SendMessage}锛屽弬鏁� {@code sfzh/title/content/phone/url/key}锛�
+ * 杩斿洖 JSON锛堝垽瀹氬瓧娈� {@code success == 1}锛夈��
+ * <p>
+ * 杩佺Щ璇存槑锛氬師瀹炵幇涓� {@code com.ruoyi.common.utils.sms.smsUtils.sendChat}锛屽叾涓湴鍧�銆佸瘑閽ャ��
+ * 鏍囬鏂囨銆佸唴瀹规枃妗堥兘鏄‖缂栫爜锛涜繖閲屽叏閮ㄦ彁涓哄彲閰嶇疆锛堥粯璁ゅ�间笌鍘熺‖缂栫爜涓�鑷达級锛�
+ * 渚夸簬鍚庣画鎸夋満鏋�/浠诲姟绫诲瀷鍖哄垎鏂囨锛岃 {@link MessageProperties.ShiyiWechat}銆�
+ */
+@Slf4j
+@Component
+public class ShiyiMpApi {
+
+    private final MessageProperties properties;
+
+    public ShiyiMpApi(MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * 鍙戦�佸叕浼楀彿娑堟伅
+     *
+     * @param url    澶栭摼鍦板潃
+     * @param phone  鎵嬫満鍙�
+     * @param idCard 韬唤璇佸彿
+     * @return 绗笁鏂瑰師濮嬪搷搴�
+     */
+    public String sendMessage(String url, String phone, String idCard) {
+        MessageProperties.ShiyiWechat cfg = properties.getWechat().getShiyi();
+        String urlTemp = cfg.getUrl()
+                + "?sfzh=" + idCard
+                + "&title=" + cfg.getTitle()
+                + "&content=" + cfg.getContent()
+                + "&phone=" + phone
+                + "&url=" + url
+                + "&key=" + cfg.getKey();
+        String sendMsg = "";
+        try {
+            log.info("銆怱hiyiMpApi銆戝競涓�寰俊鍏紬鍙疯姹傚弬鏁帮細{}", urlTemp);
+            sendMsg = HttpUtils.sendPost(urlTemp);
+            log.info("銆怱hiyiMpApi銆戝競涓�寰俊鍏紬鍙疯繑鍥炲�硷細{}", sendMsg);
+        } catch (Exception ex) {
+            sendMsg = ex.getMessage();
+            log.error("銆怱hiyiMpApi銆戝競涓�寰俊鍏紬鍙峰彂閫佸紓甯革細{}", ex.getMessage(), ex);
+        }
+        return sendMsg;
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.java
new file mode 100644
index 0000000..689417f
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.java
@@ -0,0 +1,72 @@
+package com.ruoyi.message.wechat.provider.hzszlyy;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSender;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * 鏉窞甯備竴寰俊鍏紬鍙峰彂閫佹柟锛坽@code hzszlyy} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛氬競涓�鑷湁缃戝叧锛岃繑鍥� JSON 鐨� {@code success == 1} 涓烘垚鍔熴��
+ * 浠g爜鏉ユ簮锛歿@code RyTask.hzszlyy 鍏紬鍙峰垎鏀瘆 + {@code RedisMqReceiver.hzszlyy 鍒嗘敮} +
+ * {@code SmsController./sms/sendChat}锛堣涓轰繚鎸佷笉鍙橈級銆�
+ * <p>
+ * 娉ㄦ剰锛氬競涓�鍏紬鍙�<b>涓嶅仛鏈烘瀯閰嶇疆鏍¢獙</b>锛堝師浠g爜娉ㄩ噴銆屽競涓�鍖婚櫌 涓嶆牎楠屻�嶏級锛�
+ * 璋冪敤鏂归渶淇濈暀璇ュ樊寮傦紝涓嶈濂楃敤鏂板崕閭e {@code wxqqxx} 鏍¢獙銆�
+ */
+@Slf4j
+@Component
+public class ShiyiMpSender implements WechatSender {
+
+    /**
+     * 娓犻亾 key锛屽井淇″叕浼楀彿閫氶亾涓嬩笌鐭俊閫氶亾鍚屽悕锛坽@code hzszlyy}锛夛紝鐢卞悇鑷殑宸ュ巶鍖哄垎
+     */
+    public static final String KEY = "hzszlyy";
+
+    private final ShiyiMpApi shiyiMpApi;
+
+    public ShiyiMpSender(ShiyiMpApi shiyiMpApi) {
+        this.shiyiMpApi = shiyiMpApi;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "鏉窞甯備竴寰俊鍏紬鍙凤紙success==1 鍒ゅ畾锛�";
+    }
+
+    @Override
+    public SendResult send(WechatSendRequest request) {
+        if (request == null || request.getPhone() == null || request.getPhone().trim().isEmpty()) {
+            return SendResult.fail(KEY, MessageChannel.WECHAT, "鎵嬫満鍙蜂负绌�", null);
+        }
+        try {
+            String raw = shiyiMpApi.sendMessage(request.getUrl(), request.getPhone(), request.getIdCard());
+            Map map = JSONObject.parseObject(raw, Map.class);
+            Boolean success = false;
+            if (map != null && !map.isEmpty() && map.get("success") != null) {
+                Integer value = (Integer) map.get("success");
+                success = value != null && value == 1;
+            }
+            if (success) {
+                return SendResult.success(KEY, MessageChannel.WECHAT, raw);
+            }
+            Object msg = map == null ? null : map.get("msg");
+            return SendResult.fail(KEY, MessageChannel.WECHAT,
+                    msg == null ? "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�" : msg.toString(), raw);
+        } catch (Exception e) {
+            log.error("銆恵}銆戝競涓�鍏紬鍙峰彂閫佸け璐ワ細{}", KEY, e.getMessage(), e);
+            return SendResult.fail(KEY, MessageChannel.WECHAT, "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�", null);
+        }
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.java
new file mode 100644
index 0000000..a63b3f8
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.java
@@ -0,0 +1,86 @@
+package com.ruoyi.message.wechat.provider.sdk;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSender;
+import com.ruoyi.message.wechat.support.WxMpUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * 寰俊鍏紬鍙� SDK 鍙戦�佹柟锛坽@code wxmp-sdk} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛氱洿鎺ヤ娇鐢ㄥ井淇″畼鏂� SDK锛坽@code weixin-java-mp}锛夛紝鏀寔鏂囨湰瀹㈡湇娑堟伅涓庢ā鏉挎秷鎭紝
+ * 闇�瑕� <b>openid</b>锛堣�屼笉鏄墜鏈哄彿锛夛紝鍥犳鍏ュ弬璧� {@link WechatSendRequest#getOpenid()}銆�
+ * <p>
+ * 鐜扮姸锛氳鑳藉姏鍘熷厛鍙湁 {@code WxMpUtils} 涓�涓伐鍏风被锛�<b>娌℃湁浠讳綍涓氬姟璋冪敤鐐�</b>銆�
+ * 鏀跺彛鍚庣敱宸ュ巶缁熶竴璋冨害锛屽悗缁嫢瑕佺粰銆屽井淇″皬绋嬪簭/鍏紬鍙枫�嶇被浠诲姟鐢ㄥ畼鏂� SDK 鍙戦�侊紝鐩存帴璧拌繖閲屻��
+ * <p>
+ * 鎵╁睍鍙傛暟锛�
+ * <ul>
+ *   <li>{@code appId} / {@code appSecret}锛氬叕浼楀彿鍑嵁锛堝繀濉級锛�</li>
+ *   <li>{@code templateData}锛氭ā鏉挎暟鎹� {@code Map<String,String>}锛堟ā鏉挎秷鎭敤锛夈��</li>
+ * </ul>
+ */
+@Slf4j
+@Component
+public class WxMpSdkSender implements WechatSender {
+
+    /**
+     * 娓犻亾 key
+     */
+    public static final String KEY = "wxmp-sdk";
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "寰俊鍏紬鍙峰畼鏂� SDK锛堝鏈嶆枃鏈秷鎭� / 妯℃澘娑堟伅锛屾寜 openid 鍙戦�侊級";
+    }
+
+    @Override
+    public SendResult send(WechatSendRequest request) {
+        if (request == null || StringUtils.isEmpty(request.getOpenid())) {
+            return SendResult.fail(KEY, MessageChannel.WECHAT, "openid 涓虹┖", null);
+        }
+        Object appId = request.getExtra("appId");
+        Object appSecret = request.getExtra("appSecret");
+        if (appId == null || appSecret == null) {
+            return SendResult.fail(KEY, MessageChannel.WECHAT, "鍏紬鍙� appId/appSecret 鏈厤缃�", null);
+        }
+
+        try {
+            WxMpUtils wxMpUtils = WxMpUtils.of(String.valueOf(appId), String.valueOf(appSecret));
+            if (StringUtils.isNotEmpty(request.getTemplateId())) {
+                return sendTemplate(wxMpUtils, request);
+            }
+            boolean ok = wxMpUtils.sendTextMessage(request.getOpenid(), request.getContent());
+            if (ok) {
+                return SendResult.success(KEY, MessageChannel.WECHAT, null);
+            }
+            return SendResult.fail(KEY, MessageChannel.WECHAT, "鍏紬鍙锋秷鎭彂閫佸け璐�", null);
+        } catch (Exception e) {
+            log.error("銆恵}銆戝叕浼楀彿娑堟伅鍙戦�佸紓甯革細{}", KEY, e.getMessage(), e);
+            return SendResult.fail(KEY, MessageChannel.WECHAT, "鍏紬鍙锋秷鎭彂閫佸紓甯革細" + e.getMessage(), null);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private SendResult sendTemplate(WxMpUtils wxMpUtils, WechatSendRequest request) {
+        Object data = request.getExtra("templateData");
+        Map<String, String> dataMap = data instanceof Map ? (Map<String, String>) data : null;
+        String msgId = wxMpUtils.sendTemplateMessage(request.getOpenid(), request.getTemplateId(),
+                request.getUrl(), dataMap, null);
+        if (StringUtils.isNotEmpty(msgId)) {
+            return SendResult.success(KEY, MessageChannel.WECHAT, msgId).withCode(msgId);
+        }
+        return SendResult.fail(KEY, MessageChannel.WECHAT, "鍏紬鍙锋ā鏉挎秷鎭彂閫佸け璐�", null);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.java
new file mode 100644
index 0000000..adca93d
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.java
@@ -0,0 +1,122 @@
+package com.ruoyi.message.wechat.provider.xh;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.message.wechat.WechatMpConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 鏂板崕鍖婚櫌鍏紬鍙� API銆�
+ * <p>
+ * 瀵规帴鐗瑰緛锛歅OST JSON 鎶ユ枃锛岀鍚� {@code sign = MD5(appSecret + body)} 鏀惧湪璇锋眰澶达紝
+ * 缃戝叧鍦板潃鏉ヨ嚜鏈烘瀯绾ч厤缃紙{@code WxGZHEnum}锛夈��
+ * <p>
+ * 杩佺Щ璇存槑锛氬師閫昏緫鍒嗘暎鍦� {@code RyTask.getWXCode}銆亄@code RedisMqReceiver.getWXCode}銆�
+ * {@code ServiceSubtaskServiceImpl.getWXCode} 涓変唤鎷疯礉閲岋紝姝ゅ鍚堝苟涓轰竴浠斤紙琛屼负淇濇寔涓嶅彉锛夈��
+ */
+@Slf4j
+@Component
+public class XinHuaMpApi {
+
+    private final com.ruoyi.message.config.MessageProperties properties;
+
+    public XinHuaMpApi(com.ruoyi.message.config.MessageProperties properties) {
+        this.properties = properties;
+    }
+
+    /**
+     * 鍙戦�佸叕浼楀彿娑堟伅锛堥粯璁や笉鍏抽棴 HTML 杞箟锛岀瓑浠� {@code RyTask.getWXCode}锛�
+     */
+    public String sendMessage(String idcard, String url, String taskName, String taskDesc,
+                              String phone, String patientName, String patientId, WechatMpConfig config) {
+        return sendMessage(idcard, url, taskName, taskDesc, phone, patientName, patientId, config, false);
+    }
+
+    /**
+     * 鍙戦�佸叕浼楀彿娑堟伅
+     *
+     * @param idcard         韬唤璇佸彿
+     * @param url            澶栭摼鍦板潃
+     * @param taskName       鏍囬
+     * @param taskDesc       鍐呭
+     * @param phone          鎵嬫満鍙�
+     * @param patientName    鎮h�呭鍚�
+     * @param patientId      HIS 渚ф偅鑰匢D
+     * @param config         鏈烘瀯绾у叕浼楀彿閰嶇疆
+     * @param disableHtmlEscaping 鏄惁鍏抽棴 Gson 鐨� HTML 杞箟
+     *                      <p>
+     *                      鈿狅笍 绔欑偣宸紓锛堝繀椤诲尯鍒嗭級锛歿@code RedisMqReceiver.getWXCode} 鐢ㄧ殑鏄�
+     *                      {@code new GsonBuilder().disableHtmlEscaping()}锛岃��
+     *                      {@code RyTask.getWXCode} / {@code ServiceSubtaskServiceImpl.getWXCode}
+     *                      鐢ㄧ殑鏄� {@code new Gson()}锛堜細鎶� {@code < > & = '} 杞垚 unicode 杞箟锛夈��
+     *                      涓よ�呬骇鍑虹殑鎶ユ枃浣撲笉鍚岋紝杩涜�屽奖鍝� sign 绛惧悕銆傛澶勬寜璋冪敤鏂瑰尯鍒嗭紝淇濇寔绾夸笂琛屼负銆�
+     * @return 绗笁鏂瑰師濮嬪搷搴�
+     */
+    public String sendMessage(String idcard, String url, String taskName, String taskDesc,
+                              String phone, String patientName, String patientId, WechatMpConfig config,
+                              boolean disableHtmlEscaping) {
+        XinHuaWXReq req = new XinHuaWXReq();
+        req.setService(properties.getWechat().getXinhua().getService());
+        req.setIdcard(idcard);
+        req.setUrl(url);
+        req.setPatientid(patientId);
+        req.setPatientname(patientName);
+        req.setMobile(phone);
+        req.setMedcardno(null);
+        req.setTitlename(taskName);
+        req.setContent(taskDesc);
+        req.setAppid(config.getAppid());
+
+        log.info("銆怷inHuaMpApi銆戝井淇″叕浼楀彿璇锋眰鍙傛暟锛歿}锛坉isableHtmlEscaping={}锛�", req, disableHtmlEscaping);
+        String body;
+        if (disableHtmlEscaping) {
+            GsonBuilder gb = new GsonBuilder();
+            gb.disableHtmlEscaping();
+            body = gb.create().toJson(req);
+        } else {
+            body = new Gson().toJson(req);
+        }
+        String sign = md5(config.getAppSecret().concat(body));
+        Map<String, String> headerMap = new HashMap<>();
+        headerMap.put("sign", sign);
+        String result = HttpUtils.sendPostByHeader(config.getAddress(), body, headerMap);
+        log.info("銆怷inHuaMpApi銆戝井淇″叕浼楀彿杩斿洖鍙傛暟锛歿}", result);
+        return result;
+    }
+
+    /**
+     * MD5 杞崄鍏繘鍒跺皬鍐欙紙绛変环鍘� {@code getWXCode} 閲岀殑 {@code encode}锛�
+     */
+    private String md5(String arg) {
+        if (arg == null) {
+            arg = "";
+        }
+        try {
+            MessageDigest md5 = MessageDigest.getInstance("MD5");
+            md5.update(arg.getBytes(StandardCharsets.UTF_8));
+            return toHex(md5.digest());
+        } catch (Exception e) {
+            log.error("銆怷inHuaMpApi銆慚D5 绛惧悕澶辫触锛歿}", e.getMessage(), e);
+            return "";
+        }
+    }
+
+    private String toHex(byte[] hash) {
+        StringBuilder hexString = new StringBuilder();
+        for (byte b : hash) {
+            String hex = Integer.toHexString(0xff & b);
+            if (hex.length() == 1) {
+                hexString.append('0');
+            }
+            hexString.append(hex);
+        }
+        return hexString.toString();
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.java
new file mode 100644
index 0000000..4f1d8df
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.java
@@ -0,0 +1,113 @@
+package com.ruoyi.message.wechat.provider.xh;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.wechat.WechatMpConfig;
+import com.ruoyi.message.wechat.WechatMpConfigProvider;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSender;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * 鏂板崕鍖婚櫌寰俊鍏紬鍙峰彂閫佹柟锛坽@code xh} 閫氶亾锛夈��
+ * <p>
+ * 瀵规帴鐗瑰緛锛歅OST JSON + {@code sign=MD5(appSecret+body)}锛屾垚鍔熷垽瀹氫负杩斿洖 JSON 鐨� {@code succ == true}銆�
+ * <p>
+ * 绔欑偣宸紓锛堣皟鐢ㄦ柟闇�淇濈暀锛夛細
+ * <ul>
+ *   <li>闇�瑕佹満鏋勭骇鍏紬鍙烽厤缃紙appid/appSecret/鍦板潃锛夛紝閰嶇疆涓嶅叏鏃剁洿鎺ュけ璐ワ紱</li>
+ *   <li>瑕佹眰 HIS 渚ф偅鑰匢D 闈炵┖銆�</li>
+ * </ul>
+ * 浠g爜鏉ユ簮锛歿@code RyTask 鍏紬鍙峰垎鏀瘆 + {@code RedisMqReceiver 鍏紬鍙峰垎鏀瘆 +
+ * {@code ServiceSubtaskServiceImpl.wechatSubTask}锛堣涓轰繚鎸佷笉鍙橈級銆�
+ */
+@Slf4j
+@Component
+public class XinHuaMpSender implements WechatSender {
+
+    /**
+     * 娓犻亾 key锛屼笌 {@code spring.profiles.active=xh} 瀵瑰簲
+     */
+    public static final String KEY = "xh";
+
+    private final ObjectProvider<WechatMpConfigProvider> configProvider;
+
+    private final XinHuaMpApi xinHuaMpApi;
+
+    public XinHuaMpSender(ObjectProvider<WechatMpConfigProvider> configProvider, XinHuaMpApi xinHuaMpApi) {
+        this.configProvider = configProvider;
+        this.xinHuaMpApi = xinHuaMpApi;
+    }
+
+    @Override
+    public String key() {
+        return KEY;
+    }
+
+    @Override
+    public String description() {
+        return "鏂板崕鍖婚櫌寰俊鍏紬鍙凤紙sign 绛惧悕锛宻ucc 鍒ゅ畾锛�";
+    }
+
+    @Override
+    public SendResult send(WechatSendRequest request) {
+        if (request == null) {
+            return SendResult.fail(KEY, MessageChannel.WECHAT, "銆愬叕浼楀彿銆戣姹傚弬鏁颁负绌�", null);
+        }
+
+        WechatMpConfig config = resolveConfig(request.getOrgid());
+        if (config == null || !config.isComplete()) {
+            return SendResult.fail(KEY, MessageChannel.WECHAT,
+                    "銆愬叕浼楀彿銆戣鏈烘瀯鐨勫叕浼楀彿閰嶇疆淇℃伅涓嶅叏锛屾棤娉曢�氳繃鍏紬鍙峰彂閫�", null);
+        }
+
+        if (StringUtils.isEmpty(request.getPatidHis())) {
+            return SendResult.fail(KEY, MessageChannel.WECHAT,
+                    "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�,his绯荤粺鐨勬偅鑰卛d涓虹┖", null);
+        }
+
+        try {
+            String raw = xinHuaMpApi.sendMessage(
+                    request.getIdCard(),
+                    request.getUrl(),
+                    request.getTitle(),
+                    request.getContent(),
+                    request.getPhone(),
+                    request.getPatientName(),
+                    request.getPatidHis(),
+                    config,
+                    request.isDisableHtmlEscaping());
+
+            Map map = JSONObject.parseObject(raw, Map.class);
+            boolean success = map != null && !map.isEmpty()
+                    && map.get("succ") != null
+                    && Boolean.parseBoolean(map.get("succ").toString());
+            if (success) {
+                return SendResult.success(KEY, MessageChannel.WECHAT, raw);
+            }
+            Object msg = map == null ? null : map.get("msg");
+            String message = msg == null ? "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�" : msg.toString();
+            log.error("銆恵}銆戝叕浼楀彿鍙戦�佸け璐ワ紝閿欒淇℃伅锛歿}", KEY, message);
+            return SendResult.fail(KEY, MessageChannel.WECHAT, message, raw);
+        } catch (Exception e) {
+            log.error("銆恵}銆戝叕浼楀彿鍙戦�佸紓甯革細{}", KEY, e.getMessage(), e);
+            return SendResult.fail(KEY, MessageChannel.WECHAT,
+                    "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐ワ紝鍘熷洜锛�" + e.getMessage(), null);
+        }
+    }
+
+    private WechatMpConfig resolveConfig(String orgid) {
+        WechatMpConfigProvider provider = configProvider.getIfAvailable();
+        if (provider == null) {
+            log.warn("銆恵}銆戞湭鎵惧埌 WechatMpConfigProvider 瀹炵幇锛屾棤娉曡幏鍙栨満鏋勫叕浼楀彿閰嶇疆", KEY);
+            return null;
+        }
+        return provider.getConfig(orgid);
+    }
+}
diff --git a/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.java
new file mode 100644
index 0000000..9ecc11b
--- /dev/null
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.java
@@ -0,0 +1,63 @@
+package com.ruoyi.message.wechat.provider.xh;
+
+import lombok.Data;
+
+/**
+ * 鏂板崕鍖婚櫌鍏紬鍙峰叆鍙傘��
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.smartor.domain.XinHuaWXReq}锛堝甫 swagger/Excel 娉ㄨВ锛夛紝
+ * 杩佺Щ鍒版湰妯″潡鍚庡彧淇濈暀浼犺緭瀛楁锛屽瓧娈靛悕涓� JSON 鎶ユ枃淇濇寔涓�鑷达紙涓嶈兘鏀瑰悕锛屽惁鍒欏奖鍝嶅鏂硅В鏋愶級銆�
+ */
+@Data
+public class XinHuaWXReq {
+
+    /**
+     * 鎺ュ彛鏈嶅姟鍚嶏紝鍥哄畾鍊�
+     */
+    private String service = "smarthos.pat.notice";
+
+    /**
+     * 搴旂敤缂栧彿
+     */
+    private String appid;
+
+    /**
+     * 鎮h�呯紪鍙�
+     */
+    private String patientid;
+
+    /**
+     * 鎮h�呭鍚�
+     */
+    private String patientname;
+
+    /**
+     * 璇佷欢鍙�
+     */
+    private String idcard;
+
+    /**
+     * 鎵嬫満鍙风爜
+     */
+    private String mobile;
+
+    /**
+     * 灏辫瘖鍗″彿
+     */
+    private String medcardno;
+
+    /**
+     * 閫氱煡鍐呭
+     */
+    private String titlename;
+
+    /**
+     * 閾炬帴鍦板潃
+     */
+    private String content;
+
+    /**
+     * 璇︽儏鍦板潃
+     */
+    private String url;
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/WxMpUtils.java b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/support/WxMpUtils.java
similarity index 87%
rename from ruoyi-common/src/main/java/com/ruoyi/common/utils/WxMpUtils.java
rename to ruoyi-message/src/main/java/com/ruoyi/message/wechat/support/WxMpUtils.java
index b6d51db..0d96d0b 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/WxMpUtils.java
+++ b/ruoyi-message/src/main/java/com/ruoyi/message/wechat/support/WxMpUtils.java
@@ -1,4 +1,4 @@
-package com.ruoyi.common.utils;
+package com.ruoyi.message.wechat.support;
 
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.exception.WxErrorException;
@@ -8,13 +8,18 @@
 import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
-import org.springframework.stereotype.Component;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.Map;
 
 /**
- * 寰俊鍏紬鍙锋秷鎭彂閫佸伐鍏风被
- * 鏀寔锛氭枃鏈鏈嶆秷鎭�佹ā鏉挎秷鎭�
+ * 寰俊鍏紬鍙锋秷鎭彂閫佸伐鍏风被锛堝井淇″畼鏂� SDK 閫氶亾锛夈��
+ * <p>
+ * 鏀寔锛氭枃鏈鏈嶆秷鎭�佹ā鏉挎秷鎭��
+ * <p>
+ * 杩佺Щ璇存槑锛氬師绫讳负 {@code com.ruoyi.common.utils.WxMpUtils}锛岃涓烘湭鏀瑰姩锛屼粎鎹㈠寘銆�
+ * 鐜扮姸锛氬叏椤圭洰<b>娌℃湁涓氬姟璋冪敤鐐�</b>锛堝彧鏈� {@code SysLoginController} 涓�
+ * {@code WeChatService} 閲岀殑娉ㄩ噴/娴嬭瘯浠g爜锛夛紝灞炰簬銆屽凡鍏峰鑳藉姏浣嗘湭鎺ュ叆銆嶇殑閫氶亾銆�
  */
 @Slf4j
 public class WxMpUtils {
@@ -40,8 +45,8 @@
     // -------------------------------------------------------------------------
 
     /**
-     * 鍚戞寚瀹� openid 鐨勭敤鎴峰彂閫佹枃鏈鏈嶆秷鎭�
-     * 娉ㄦ剰锛氱敤鎴烽渶鍦�48灏忔椂鍐呬笌鍏紬鍙锋湁杩囦氦浜掓墠鍙彂閫�
+     * 鍚戞寚瀹� openid 鐨勭敤鎴峰彂閫佹枃鏈鏈嶆秷鎭��
+     * 娉ㄦ剰锛氱敤鎴烽渶鍦�48灏忔椂鍐呬笌鍏紬鍙锋湁杩囦氦浜掓墠鍙彂閫併��
      *
      * @param openid  鐢ㄦ埛鐨勫井淇� openid
      * @param content 娑堟伅鍐呭
@@ -78,7 +83,6 @@
      * @param templateId 妯℃澘娑堟伅 ID锛堝湪寰俊鍏紬骞冲彴閰嶇疆锛�
      * @param url        鐐瑰嚮娑堟伅鍚庣殑璺宠浆 URL锛屼笉闇�瑕佽烦杞彲浼� null
      * @param dataMap    妯℃澘鏁版嵁锛宬ey 涓烘ā鏉垮瓧娈靛悕锛寁alue 涓� WxMpTemplateData锛堝惈鍊煎拰棰滆壊锛�
-     *                   绀轰緥锛歿"first": new WxMpTemplateData("first", "浣犲ソ", "#173177"), ...}
      * @return 鍙戦�佹垚鍔熻繑鍥炲井淇¤繑鍥炵殑 msgid锛屽け璐ヨ繑鍥� null
      */
     public String sendTemplateMessage(String openid, String templateId, String url, Map<String, WxMpTemplateData> dataMap) {
@@ -112,13 +116,13 @@
     }
 
     /**
-     * 鍚戞寚瀹� openid 鐨勭敤鎴峰彂閫佹ā鏉挎秷鎭紙绠�鍖栫増锛寁alue 涓嶈缃鑹诧級
+     * 鍚戞寚瀹� openid 鐨勭敤鎴峰彂閫佹ā鏉挎秷鎭紙绠�鍖栫増锛寁alue 缁熶竴浣跨敤榛樿棰滆壊锛�
      *
-     * @param openid     鐢ㄦ埛鐨勫井淇� openid
-     * @param templateId 妯℃澘娑堟伅 ID
-     * @param url        鐐瑰嚮娑堟伅鍚庣殑璺宠浆 URL锛屼笉闇�瑕佽烦杞彲浼� null
-     * @param dataMap    妯℃澘鏁版嵁锛宬ey 涓烘ā鏉垮瓧娈靛悕锛寁alue 涓哄瓧娈垫樉绀虹殑鏂囨湰鍐呭
-     *                   绀轰緥锛歿"first": "浣犲ソ", "keyword1": "2024-01-01", "remark": "鎰熻阿浣跨敤"}
+     * @param openid       鐢ㄦ埛鐨勫井淇� openid
+     * @param templateId   妯℃澘娑堟伅 ID
+     * @param url          鐐瑰嚮娑堟伅鍚庣殑璺宠浆 URL锛屼笉闇�瑕佽烦杞彲浼� null
+     * @param dataMap      妯℃澘鏁版嵁锛宬ey 涓烘ā鏉垮瓧娈靛悕锛寁alue 涓哄瓧娈垫樉绀虹殑鏂囨湰鍐呭
+     * @param defaultColor 榛樿棰滆壊
      * @return 鍙戦�佹垚鍔熻繑鍥炲井淇¤繑鍥炵殑 msgid锛屽け璐ヨ繑鍥� null
      */
     public String sendTemplateMessage(String openid, String templateId, String url, Map<String, String> dataMap, String defaultColor) {
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsert.asmx b/ruoyi-message/src/main/resources/wsdl/MessagingInsert.asmx
similarity index 100%
rename from ruoyi-system/src/main/java/WebServiceClient/MessagingInsert.asmx
rename to ruoyi-message/src/main/resources/wsdl/MessagingInsert.asmx
diff --git a/ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePrefixBindingCheck.java b/ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePrefixBindingCheck.java
new file mode 100644
index 0000000..6dd43f7
--- /dev/null
+++ b/ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePrefixBindingCheck.java
@@ -0,0 +1,165 @@
+package com.ruoyi.message.config;
+
+import com.ruoyi.message.MessageChannel;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSender;
+import com.ruoyi.message.sms.SmsSenderFactory;
+import com.ruoyi.message.sms.provider.shiyi.ShiyiSmsUtil;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSender;
+import com.ruoyi.message.wechat.WechatSenderFactory;
+import org.springframework.boot.context.properties.bind.Bindable;
+import org.springframework.boot.context.properties.bind.Binder;
+import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
+import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.env.StandardEnvironment;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 銆屾柊澧� {@code message.*} 鍓嶇紑椤广�嶇殑缁戝畾涓庡伐鍘傝閰嶆牎楠岋紙涓嶄緷璧� JUnit锛夈��
+ * <p>
+ * 瑕嗙洊涓や欢浜嬶細
+ * <ol>
+ *   <li>{@code message.sms.*} / {@code message.wechat.*} 鑳界粦鍒板搴旂殑宓屽瀛楁锛屾湭瑕嗙洊鐨勯」鍥炶惤榛樿鍊硷紱</li>
+ *   <li>宸ュ巶鎸� key 璺敱纭疄鏄�岃皟鐢ㄥ埌瀵瑰簲鍙戦�佹柟銆嶁�斺�旇繖鏄洓涓珯鐐瑰彂閫侀摼璺噷鏈湴鍞竴鑳介獙璇佺殑涓�鐜��</li>
+ * </ol>
+ */
+public final class MessagePrefixBindingCheck {
+
+    private static int failed = 0;
+
+    private MessagePrefixBindingCheck() {
+    }
+
+    public static void main(String[] args) throws Exception {
+        String[] yaml = {
+                "message:",
+                "  sms:",
+                "    shiyi:",
+                "      ws-url: http://his.example.com:7790/MediInfoHis.svc",
+                "      default-caozuoydm: OPR001",
+                "    messaging-insert:",
+                "      ws-url: http://msg.example.com:8081/MessagingInsert.asmx",
+                "  wechat:",
+                "    shiyi:",
+                "      title: 鑷畾涔夋爣棰�",
+                "    xinhua:",
+                "      service: custom.service",
+        };
+        ConfigurableEnvironment environment = environment(yaml);
+        Binder binder = new Binder(ConfigurationPropertySources.get(environment));
+
+        // ---------- 1) 鍓嶇紑椤圭粦瀹� ----------
+        MessageProperties.Sms sms = binder
+                .bind(ConfigurationPropertyName.of("message.sms"), Bindable.of(MessageProperties.Sms.class))
+                .orElseGet(MessageProperties.Sms::new);
+        MessageProperties.Wechat wechat = binder
+                .bind(ConfigurationPropertyName.of("message.wechat"), Bindable.of(MessageProperties.Wechat.class))
+                .orElseGet(MessageProperties.Wechat::new);
+
+        check("message.sms.shiyi.ws-url", "http://his.example.com:7790/MediInfoHis.svc",
+                sms.getShiyi().getWsUrl());
+        check("message.sms.shiyi.default-caozuoydm", "OPR001", sms.getShiyi().getDefaultCaozuoydm());
+        check("message.sms.messaging-insert.ws-url", "http://msg.example.com:8081/MessagingInsert.asmx",
+                sms.getMessagingInsert().getWsUrl());
+        check("message.wechat.shiyi.title", "鑷畾涔夋爣棰�", wechat.getShiyi().getTitle());
+        check("message.wechat.xinhua.service", "custom.service", wechat.getXinhua().getService());
+        // 鍚岀粍鏈鐩栭」搴斿洖钀介粯璁ゅ��
+        check("message.wechat.shiyi.url锛堝洖钀介粯璁わ級", "http://192.200.54.14:5003/sfjk/SendMessage",
+                wechat.getShiyi().getUrl());
+        check("message.sms.shiyi.ws-url 榛樿鍊间笉涓�", "http://192.178.0.104:7790/MediInfoHis.svc",
+                new MessageProperties.Sms().getShiyi().getWsUrl());
+
+        // ---------- 2) 宸ュ巶璺敱纭疄璋冨埌瀵瑰簲鍙戦�佹柟 ----------
+        SmsSenderFactory smsFactory = new SmsSenderFactory(Collections.<SmsSender>singletonList(new CountingSmsSender()));
+        WechatSenderFactory wechatFactory = new WechatSenderFactory(Collections.<WechatSender>singletonList(new CountingWechatSender()));
+
+        SendResult smsResult = smsFactory.send("probe-channel", SmsSendRequest.of("13500000001", "鍐呭"));
+        check("鐭俊宸ュ巶鎸� key 璺敱鍒板搴斿彂閫佹柟", "true", String.valueOf(smsResult.isOk()));
+
+        SendResult wechatResult = wechatFactory.send("probe-channel", new WechatSendRequest());
+        check("鍏紬鍙峰伐鍘傛寜 key 璺敱鍒板搴斿彂閫佹柟", "true", String.valueOf(wechatResult.isOk()));
+
+        try {
+            smsFactory.send("涓嶅瓨鍦ㄧ殑娓犻亾", SmsSendRequest.of("13500000001", "鍐呭"));
+            check("鏈煡娓犻亾搴旀姏 SendException", "鎶涘紓甯�", "娌℃姏");
+        } catch (com.ruoyi.message.SendException e) {
+            check("鏈煡娓犻亾搴旀姏 SendException", "鎶涘紓甯�", "鎶涘紓甯�");
+        }
+
+        // ---------- 3) ShiyiSmsUtil 浠嶈兘姝e父鏋勯�狅紙淇濆簳鍥炶皟/鍙傛暟鏍¢獙琛屼负涓嶄涪锛� ----------
+        ShiyiSmsUtil shiyiSmsUtil = new ShiyiSmsUtil(new MessageProperties(new RootMessageProperties()));
+        boolean paramChecked = false;
+        try {
+            shiyiSmsUtil.sendSms(null);
+        } catch (IllegalArgumentException e) {
+            paramChecked = "鐭俊璇锋眰涓嶈兘涓虹┖".equals(e.getMessage());
+        }
+        check("ShiyiSmsUtil 鍏ュ弬鏍¢獙浠嶇敓鏁�", "true", String.valueOf(paramChecked));
+
+        System.out.println();
+        if (failed == 0) {
+            System.out.println("===== message.* 缁戝畾涓庡伐鍘傝矾鐢辨牎楠屽叏閮ㄩ�氳繃 =====");
+        } else {
+            System.out.println("===== message.* 缁戝畾涓庡伐鍘傝矾鐢辨牎楠屽け璐� " + failed + " 椤� =====");
+            System.exit(1);
+        }
+    }
+
+    private static ConfigurableEnvironment environment(String[] inlineYaml) throws IOException {
+        ConfigurableEnvironment environment = new StandardEnvironment();
+        environment.getPropertySources()
+                .remove(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
+        environment.getPropertySources()
+                .remove(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
+        org.springframework.boot.env.YamlPropertySourceLoader loader =
+                new org.springframework.boot.env.YamlPropertySourceLoader();
+        List<PropertySource<?>> sources = loader.load("inline.yml",
+                new org.springframework.core.io.ByteArrayResource(
+                        String.join("\n", inlineYaml).getBytes(java.nio.charset.StandardCharsets.UTF_8)));
+        for (PropertySource<?> source : sources) {
+            environment.getPropertySources().addLast(source);
+        }
+        return environment;
+    }
+
+    private static void check(String key, String expected, String actual) {
+        boolean ok = expected.equals(actual);
+        if (!ok) {
+            failed++;
+        }
+        System.out.println((ok ? "[OK]   " : "[FAIL] ") + key + "  鏈熸湜=[" + expected + "]  瀹為檯=[" + actual + "]");
+    }
+
+    /** 鎺㈤拡鐭俊鍙戦�佹柟 */
+    static class CountingSmsSender implements SmsSender {
+        @Override
+        public String key() {
+            return "probe-channel";
+        }
+
+        @Override
+        public SendResult send(SmsSendRequest request) {
+            return SendResult.success(key(), MessageChannel.SMS, "called");
+        }
+    }
+
+    /** 鎺㈤拡鍏紬鍙峰彂閫佹柟 */
+    static class CountingWechatSender implements WechatSender {
+        @Override
+        public String key() {
+            return "probe-channel";
+        }
+
+        @Override
+        public SendResult send(WechatSendRequest request) {
+            return SendResult.success(key(), MessageChannel.WECHAT, "called");
+        }
+    }
+}
diff --git a/ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePropertiesBindingCheck.java b/ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePropertiesBindingCheck.java
new file mode 100644
index 0000000..3f775a0
--- /dev/null
+++ b/ruoyi-message/src/test/java/com/ruoyi/message/config/MessagePropertiesBindingCheck.java
@@ -0,0 +1,95 @@
+package com.ruoyi.message.config;
+
+import org.springframework.boot.context.properties.bind.Bindable;
+import org.springframework.boot.context.properties.bind.Binder;
+import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
+import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
+import org.springframework.boot.env.YamlPropertySourceLoader;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.core.io.ClassPathResource;
+
+import java.util.List;
+
+/**
+ * 閰嶇疆缁戝畾鏍¢獙绋嬪簭锛堜笉渚濊禆 JUnit锛屽彲鐩存帴鐢ㄦā鍧楃殑杩愯鏃� classpath 鎵ц锛夈��
+ * <p>
+ * 瀛樺湪鐨勬剰涔夛細鎶婃暎钀界殑 {@code @Value} 鏀规垚 {@code @ConfigurationProperties} 鍚庯紝
+ * 鍓嶇紑/灞傜骇鍐欓敊<b>缂栬瘧鏈熷彂鐜颁笉浜�</b>锛屽彧浼氬湪绾夸笂鍙戠煭淇℃椂琛ㄧ幇涓哄弬鏁颁负 null銆�
+ * 鏈▼搴忕敤銆岀湡瀹炵殑鎵佸钩 yml銆嶈窇涓�娆$粦瀹氾紝鎶婅繖浜� key 閿佷綇銆�
+ * <p>
+ * 鎵ц鏂瑰紡瑙� {@code ruoyi-message/README-閰嶇疆缁戝畾鏍¢獙.md}銆�
+ */
+public final class MessagePropertiesBindingCheck {
+
+    private static int failed = 0;
+
+    private MessagePropertiesBindingCheck() {
+    }
+
+    public static void main(String[] args) throws Exception {
+        StandardEnvironment environment = new StandardEnvironment();
+        // 鍘绘帀 systemProperties / systemEnvironment锛歐indows 涓嬪畠浠殑鍚嶅瓧鏄ぇ鍐欓┘宄帮紙濡� XHSMSPATH锛夛紝
+        // ConfigurationPropertyName 涓嶆帴鍙楀ぇ鍐欙紝浼氬共鎵扮粦瀹氳瘖鏂�傜敓浜х敤 SpringApplication 鏃跺悕瀛椾細琚綊涓�鍖栥��
+        environment.getPropertySources()
+                .remove(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
+        environment.getPropertySources()
+                .remove(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
+        List<PropertySource<?>> sources = new YamlPropertySourceLoader()
+                .load("message-binding-check.yml", new ClassPathResource("message-binding-check.yml"));
+        environment.getPropertySources().addLast(sources.get(0));
+
+        Binder binder = new Binder(ConfigurationPropertySources.get(environment));
+        RootMessageProperties root = binder
+                .bind(ConfigurationPropertyName.EMPTY, Bindable.of(RootMessageProperties.class))
+                .orElseGet(RootMessageProperties::new);
+        MessageProperties properties = new MessageProperties(root);
+
+        // ---- 鏂板崕鐭俊缃戝叧 ----
+        check("xhsmsPath", "http://192.16.4.220:8092/sendSms", properties.getSms().getXhsms().getPath());
+        check("xhsmsAccount", "911124", properties.getSms().getXhsms().getAccount());
+        check("xhsmsPwd", "zW5eXe", properties.getSms().getXhsms().getPwd());
+        check("xhsmsjrm", "1069055", properties.getSms().getXhsms().getExtno());
+
+        // ---- 鍗楀崕闄勪竴 MT锛堢敤鎴风壒鍒寚鍑虹殑閭f壒閰嶇疆锛�----
+        check("sms_accountName", "S200232", properties.getSms().getMt().getAccountName());
+        check("sms_password", "lD94Yo", properties.getSms().getMt().getPassword());
+        check("sms_url", "http://open.nhyfy.cn/kapi/gw-api/hntypt/ucpmsg/send", properties.getSms().getMt().getUrl());
+        check("sms_sourceAddr", "1069100020341", properties.getSms().getMt().getSourceAddr());
+        check("sms_serviceCode", "PUSH", properties.getSms().getMt().getServiceCode());
+        check("sms_appkey", "ak-BFq4NN0TMf92J7KAioNYGz74", properties.getSms().getMt().getAppkey());
+        check("sms_flag", "銆愬崡鍗庡ぇ瀛﹂檮灞炵涓�鍖婚櫌銆�", properties.getSms().getMt().getFlag());
+
+        // ---- 闃块噷浜� ----
+        check("accessKeyId", "LTAI5tTestKeyId", properties.getSms().getAliyun().getAccessKeyId());
+        check("accessKeySecret", "testSecret", properties.getSms().getAliyun().getAccessKeySecret());
+        check("signName", "鏉窞鍒╂箹绉戞妧", properties.getSms().getAliyun().getSignName());
+
+        // ---- 鏂板椤瑰簲鍥炶惤鍒伴粯璁ゅ�� ----
+        check("message.sms.shiyi.ws-url 榛樿鍊�", "http://192.178.0.104:7790/MediInfoHis.svc",
+                properties.getSms().getShiyi().getWsUrl());
+        check("message.sms.messaging-insert.ws-url 榛樿鍊�", "http://218.108.11.29:8081/MessagingInsert.asmx",
+                properties.getSms().getMessagingInsert().getWsUrl());
+        check("message.wechat.shiyi.url 榛樿鍊�", "http://192.200.54.14:5003/sfjk/SendMessage",
+                properties.getWechat().getShiyi().getUrl());
+        check("message.wechat.xinhua.service 榛樿鍊�", "smarthos.pat.notice",
+                properties.getWechat().getXinhua().getService());
+
+        System.out.println();
+        if (failed == 0) {
+            System.out.println("===== 閰嶇疆缁戝畾鏍¢獙鍏ㄩ儴閫氳繃 =====");
+        } else {
+            System.out.println("===== 閰嶇疆缁戝畾鏍¢獙澶辫触 " + failed + " 椤� =====");
+            System.exit(1);
+        }
+    }
+
+    private static void check(String key, String expected, String actual) {
+        boolean ok = expected == null ? actual == null : expected.equals(actual);
+        if (!ok) {
+            failed++;
+        }
+        System.out.println((ok ? "[OK]   " : "[FAIL] ") + key
+                + "  鏈熸湜=" + expected + "  瀹為檯=" + actual);
+    }
+}
diff --git a/ruoyi-message/src/test/java/com/ruoyi/message/config/PerSiteBindingCheck.java b/ruoyi-message/src/test/java/com/ruoyi/message/config/PerSiteBindingCheck.java
new file mode 100644
index 0000000..749ce5a
--- /dev/null
+++ b/ruoyi-message/src/test/java/com/ruoyi/message/config/PerSiteBindingCheck.java
@@ -0,0 +1,106 @@
+package com.ruoyi.message.config;
+
+import org.springframework.boot.context.properties.bind.Bindable;
+import org.springframework.boot.context.properties.bind.Binder;
+import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
+import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
+import org.springframework.boot.env.YamlPropertySourceLoader;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.core.io.FileSystemResource;
+
+import java.util.List;
+
+/**
+ * 鐢ㄣ�屽悇绔欑偣鐪熷疄鐨� application-*.yml銆嶉�愮珯鐐规牎楠屽瓨閲忔墎骞� key 鐨勭粦瀹氥��
+ * <p>
+ * 鍙叧蹇冪煭淇�/鍏紬鍙风浉鍏� key锛屽叾浣� key 鍗充娇甯﹀崰浣嶇涔熶笉褰卞搷銆�
+ */
+public final class PerSiteBindingCheck {
+
+    private static int failed = 0;
+
+    private PerSiteBindingCheck() {
+    }
+
+    public static void main(String[] args) throws Exception {
+        String resDir = args.length > 0 ? args[0]
+                : "ruoyi-admin/src/main/resources";
+
+        checkSite(resDir, "xh", "鏂板崕",
+                new String[]{"http://192.16.4.220:8092/sms", "911124", "zW5eXe", "1069055"},
+                null, null);
+        checkSite(resDir, "hzszlyy", "甯備竴",
+                new String[]{"http://192.169.140.240:8001/sms/api/sendMessageMass", "300044", "qj0NHDegxWhj", "1069055"},
+                null, null);
+        checkSite(resDir, "sltd", "鐪佺珛鍚屽痉",
+                new String[]{"", "", "", ""},
+                null, null);
+        checkSite(resDir, "nhfy", "鍗楀崕闄勪竴",
+                new String[]{"", "", "", ""},
+                new String[]{"S200232", "lD94Yo", "http://open.nhyfy.cn/kapi/gw-api/hntypt/ucpmsg/send",
+                        "1069100020341", "PUSH", "ak-BFq4NN0TMf92J7KAioNYGz74", "銆愬崡鍗庡ぇ瀛﹂檮灞炵涓�鍖婚櫌銆�"},
+                null);
+
+        System.out.println();
+        if (failed == 0) {
+            System.out.println("===== 閫愮珯鐐圭粦瀹氭牎楠屽叏閮ㄩ�氳繃 =====");
+        } else {
+            System.out.println("===== 閫愮珯鐐圭粦瀹氭牎楠屽け璐� " + failed + " 椤� =====");
+            System.exit(1);
+        }
+    }
+
+    private static void checkSite(String resDir, String profile, String siteName,
+                                  String[] xhsms, String[] mt, String[] aliyun) throws Exception {
+        String file = resDir + "/application-" + profile + ".yml";
+        System.out.println("========== " + siteName + "锛�" + file + "锛�==========");
+
+        ConfigurableEnvironment environment = new StandardEnvironment();
+        environment.getPropertySources()
+                .remove(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME);
+        environment.getPropertySources()
+                .remove(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
+        List<PropertySource<?>> sources = new YamlPropertySourceLoader()
+                .load(file, new FileSystemResource(file));
+        for (PropertySource<?> source : sources) {
+            environment.getPropertySources().addLast(source);
+        }
+
+        Binder binder = new Binder(ConfigurationPropertySources.get(environment));
+        RootMessageProperties root = binder
+                .bind(ConfigurationPropertyName.EMPTY, Bindable.of(RootMessageProperties.class))
+                .orElseGet(RootMessageProperties::new);
+        MessageProperties p = new MessageProperties(root);
+
+        if (xhsms != null) {
+            check(siteName + ".xhsmsPath", xhsms[0], p.getSms().getXhsms().getPath());
+            check(siteName + ".xhsmsAccount", xhsms[1], p.getSms().getXhsms().getAccount());
+            check(siteName + ".xhsmsPwd", xhsms[2], p.getSms().getXhsms().getPwd());
+            check(siteName + ".xhsmsjrm", xhsms[3], p.getSms().getXhsms().getExtno());
+        }
+        if (mt != null) {
+            check(siteName + ".sms_accountName", mt[0], p.getSms().getMt().getAccountName());
+            check(siteName + ".sms_password", mt[1], p.getSms().getMt().getPassword());
+            check(siteName + ".sms_url", mt[2], p.getSms().getMt().getUrl());
+            check(siteName + ".sms_sourceAddr", mt[3], p.getSms().getMt().getSourceAddr());
+            check(siteName + ".sms_serviceCode", mt[4], p.getSms().getMt().getServiceCode());
+            check(siteName + ".sms_appkey", mt[5], p.getSms().getMt().getAppkey());
+            check(siteName + ".sms_flag", mt[6], p.getSms().getMt().getFlag());
+        }
+        if (aliyun != null) {
+            check(siteName + ".accessKeyId", aliyun[0], p.getSms().getAliyun().getAccessKeyId());
+        }
+        System.out.println();
+    }
+
+    private static void check(String key, String expected, String actual) {
+        boolean ok = expected == null ? actual == null : expected.equals(actual);
+        if (!ok) {
+            failed++;
+        }
+        System.out.println((ok ? "  [OK]   " : "  [FAIL] ") + key
+                + "  鏈熸湜=[" + expected + "]  瀹為檯=[" + actual + "]");
+    }
+}
diff --git a/ruoyi-message/src/test/resources/message-binding-check.yml b/ruoyi-message/src/test/resources/message-binding-check.yml
new file mode 100644
index 0000000..84d334a
--- /dev/null
+++ b/ruoyi-message/src/test/resources/message-binding-check.yml
@@ -0,0 +1,18 @@
+# 浠呯敤浜� MessagePropertiesBindingCheck锛氭ā鎷熷悇绔欑偣 application-<profile>.yml 鐨勩�屾牴绾ф墎骞� key銆�
+# 娉ㄦ剰锛氳繖浜� key 鍦ㄧ湡瀹為厤缃枃浠堕噷灏辨槸鏍圭骇鐨勶紝涓嶅甫浠讳綍鍓嶇紑
+xhsmsPath: http://192.16.4.220:8092/sendSms
+xhsmsAccount: 911124
+xhsmsPwd: zW5eXe
+xhsmsjrm: 1069055
+
+sms_accountName: S200232
+sms_password: lD94Yo
+sms_url: http://open.nhyfy.cn/kapi/gw-api/hntypt/ucpmsg/send
+sms_sourceAddr: 1069100020341
+sms_serviceCode: PUSH
+sms_appkey: ak-BFq4NN0TMf92J7KAioNYGz74
+sms_flag: 銆愬崡鍗庡ぇ瀛﹂檮灞炵涓�鍖婚櫌銆�
+
+accessKeyId: LTAI5tTestKeyId
+accessKeySecret: testSecret
+signName: 鏉窞鍒╂箹绉戞妧
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/MessageChannel.class b/ruoyi-message/target/classes/com/ruoyi/message/MessageChannel.class
new file mode 100644
index 0000000..29e855d
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/MessageChannel.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/SendException.class b/ruoyi-message/target/classes/com/ruoyi/message/SendException.class
new file mode 100644
index 0000000..e98e837
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/SendException.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/SendResult.class b/ruoyi-message/target/classes/com/ruoyi/message/SendResult.class
new file mode 100644
index 0000000..2ca33f8
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/SendResult.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/AliyunSmsConfig.class b/ruoyi-message/target/classes/com/ruoyi/message/config/AliyunSmsConfig.class
new file mode 100644
index 0000000..20eac4c
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/AliyunSmsConfig.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageConfigValidator.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageConfigValidator.class
new file mode 100644
index 0000000..759b5c7
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageConfigValidator.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$MessagingInsert.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$MessagingInsert.class
new file mode 100644
index 0000000..21b9ebf
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$MessagingInsert.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiSms.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiSms.class
new file mode 100644
index 0000000..d22a39f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiSms.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiWechat.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiWechat.class
new file mode 100644
index 0000000..924d7fe
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$ShiyiWechat.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Sms.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Sms.class
new file mode 100644
index 0000000..bdfcec1
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Sms.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Wechat.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Wechat.class
new file mode 100644
index 0000000..92a8fa5
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Wechat.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Xinhua.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Xinhua.class
new file mode 100644
index 0000000..b35635f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties$Xinhua.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties.class
new file mode 100644
index 0000000..9b4c6d6
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MessageProperties.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/MtSmsConfig.class b/ruoyi-message/target/classes/com/ruoyi/message/config/MtSmsConfig.class
new file mode 100644
index 0000000..4f2c70c
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/MtSmsConfig.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/RootMessageProperties.class b/ruoyi-message/target/classes/com/ruoyi/message/config/RootMessageProperties.class
new file mode 100644
index 0000000..f194772
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/RootMessageProperties.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/config/XhsmsConfig.class b/ruoyi-message/target/classes/com/ruoyi/message/config/XhsmsConfig.class
new file mode 100644
index 0000000..cb454c4
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/config/XhsmsConfig.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/AbstractSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/AbstractSmsSender.class
new file mode 100644
index 0000000..2b02a56
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/AbstractSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSendRequest.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSendRequest.class
new file mode 100644
index 0000000..dbd8698
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSendRequest.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSender.class
new file mode 100644
index 0000000..cf8bb5f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSenderFactory.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSenderFactory.class
new file mode 100644
index 0000000..89e0e27
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/SmsSenderFactory.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.class
new file mode 100644
index 0000000..264794b
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsApi.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$1.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$1.class
new file mode 100644
index 0000000..9178a21
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$1.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$SendSmsRequestAdapter.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$SendSmsRequestAdapter.class
new file mode 100644
index 0000000..7eb6527
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender$SendSmsRequestAdapter.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.class
new file mode 100644
index 0000000..7a949ef
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/aliyun/AliYunSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.class
new file mode 100644
index 0000000..e9741d9
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsApi.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.class
new file mode 100644
index 0000000..b9adc54
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/hzszlyy/ShiyiSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.class
new file mode 100644
index 0000000..7888575
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfig.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.class
new file mode 100644
index 0000000..b184b4c
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiMessageConfigProvider.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.class
new file mode 100644
index 0000000..a2bf32e
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.class
new file mode 100644
index 0000000..03fcf7f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/ls/LishuiStaticConfig.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.class
new file mode 100644
index 0000000..881667f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsApi.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.class
new file mode 100644
index 0000000..cdc8844
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/MessagingInsertSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.class
new file mode 100644
index 0000000..1e86df8
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsert.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.class
new file mode 100644
index 0000000..7056575
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertLocator.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.class
new file mode 100644
index 0000000..09a5d45
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap12Stub.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.class
new file mode 100644
index 0000000..7d0ed4e
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_BindingStub.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.class
new file mode 100644
index 0000000..97de2d2
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/messaginginsert/ws/MessagingInsertSoap_PortType.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.class
new file mode 100644
index 0000000..6215c9e
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmResp.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.class
new file mode 100644
index 0000000..2c9061e
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/MtSubmitSmUtil.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.class
new file mode 100644
index 0000000..3f0c9f9
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/nhfy/NhfySmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.class
new file mode 100644
index 0000000..ad05df9
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiHisSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.class
new file mode 100644
index 0000000..f809d90
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsRequest.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.class
new file mode 100644
index 0000000..4a19a4e
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.class
new file mode 100644
index 0000000..1ae4c9f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/shiyi/ShiyiSmsUtil.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.class
new file mode 100644
index 0000000..fd9ece5
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdResponseParser.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.class
new file mode 100644
index 0000000..5d697a8
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/SltdSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/Hello.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/Hello.class
new file mode 100644
index 0000000..6859e74
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/Hello.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.class
new file mode 100644
index 0000000..69c04f6
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/HelloResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.class
new file mode 100644
index 0000000..792be26
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReply.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.class
new file mode 100644
index 0000000..4a88b14
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReplyResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.class
new file mode 100644
index 0000000..77e219a
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReport.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.class
new file mode 100644
index 0000000..4e95d8d
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GReportResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.class
new file mode 100644
index 0000000..0a63268
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumber.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.class
new file mode 100644
index 0000000..a222e5f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSearchNumberResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.class
new file mode 100644
index 0000000..ed689e9
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSend.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.class
new file mode 100644
index 0000000..f9c0d2b
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/I5GSendResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.class
new file mode 100644
index 0000000..a2a3bf0
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/MessageSend.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.class
new file mode 100644
index 0000000..d0dd035
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/ObjectFactory.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.class
new file mode 100644
index 0000000..fe08c02
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumber.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.class
new file mode 100644
index 0000000..34d5788
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetNumberResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.class
new file mode 100644
index 0000000..743a208
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateList.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.class
new file mode 100644
index 0000000..b48b731
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetTemplateListResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.class
new file mode 100644
index 0000000..9b460b7
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserList.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.class
new file mode 100644
index 0000000..7e43a5b
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSGetUserListResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.class
new file mode 100644
index 0000000..57c146f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContent.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.class
new file mode 100644
index 0000000..eda3837
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSSaveContentResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.class
new file mode 100644
index 0000000..8cb6118
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerify.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.class
new file mode 100644
index 0000000..c2220fd
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivate.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.class
new file mode 100644
index 0000000..5dd81f0
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyPrivateResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.class
new file mode 100644
index 0000000..a54b606
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SMSVerifyResponse.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsService.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsService.class
new file mode 100644
index 0000000..f64b68d
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsService.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.class
new file mode 100644
index 0000000..b6f01c2
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/SmsServiceSoap.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/package-info.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/package-info.class
new file mode 100644
index 0000000..025664b
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/sltd/ws/package-info.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.class b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.class
new file mode 100644
index 0000000..87526b1
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/sms/provider/xh/XinHuaSmsSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfig.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfig.class
new file mode 100644
index 0000000..f250b78
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfig.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfigProvider.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfigProvider.class
new file mode 100644
index 0000000..838c2fe
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatMpConfigProvider.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSendRequest.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSendRequest.class
new file mode 100644
index 0000000..c129e3c
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSendRequest.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSender.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSender.class
new file mode 100644
index 0000000..80e6a1a
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSenderFactory.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSenderFactory.class
new file mode 100644
index 0000000..9c8de9f
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/WechatSenderFactory.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.class
new file mode 100644
index 0000000..6642449
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpApi.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.class
new file mode 100644
index 0000000..92b199c
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/hzszlyy/ShiyiMpSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.class
new file mode 100644
index 0000000..abe2a59
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/sdk/WxMpSdkSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.class
new file mode 100644
index 0000000..ed1e03c
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpApi.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.class
new file mode 100644
index 0000000..c35954b
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaMpSender.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.class
new file mode 100644
index 0000000..90dc6d3
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/provider/xh/XinHuaWXReq.class
Binary files differ
diff --git a/ruoyi-message/target/classes/com/ruoyi/message/wechat/support/WxMpUtils.class b/ruoyi-message/target/classes/com/ruoyi/message/wechat/support/WxMpUtils.class
new file mode 100644
index 0000000..310abfd
--- /dev/null
+++ b/ruoyi-message/target/classes/com/ruoyi/message/wechat/support/WxMpUtils.class
Binary files differ
diff --git a/ruoyi-message/target/classes/message-binding-check.yml b/ruoyi-message/target/classes/message-binding-check.yml
new file mode 100644
index 0000000..84d334a
--- /dev/null
+++ b/ruoyi-message/target/classes/message-binding-check.yml
@@ -0,0 +1,18 @@
+# 浠呯敤浜� MessagePropertiesBindingCheck锛氭ā鎷熷悇绔欑偣 application-<profile>.yml 鐨勩�屾牴绾ф墎骞� key銆�
+# 娉ㄦ剰锛氳繖浜� key 鍦ㄧ湡瀹為厤缃枃浠堕噷灏辨槸鏍圭骇鐨勶紝涓嶅甫浠讳綍鍓嶇紑
+xhsmsPath: http://192.16.4.220:8092/sendSms
+xhsmsAccount: 911124
+xhsmsPwd: zW5eXe
+xhsmsjrm: 1069055
+
+sms_accountName: S200232
+sms_password: lD94Yo
+sms_url: http://open.nhyfy.cn/kapi/gw-api/hntypt/ucpmsg/send
+sms_sourceAddr: 1069100020341
+sms_serviceCode: PUSH
+sms_appkey: ak-BFq4NN0TMf92J7KAioNYGz74
+sms_flag: 銆愬崡鍗庡ぇ瀛﹂檮灞炵涓�鍖婚櫌銆�
+
+accessKeyId: LTAI5tTestKeyId
+accessKeySecret: testSecret
+signName: 鏉窞鍒╂箹绉戞妧
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsert.asmx b/ruoyi-message/target/classes/wsdl/MessagingInsert.asmx
similarity index 100%
copy from ruoyi-system/src/main/java/WebServiceClient/MessagingInsert.asmx
copy to ruoyi-message/target/classes/wsdl/MessagingInsert.asmx
diff --git a/ruoyi-message/target/maven-archiver/pom.properties b/ruoyi-message/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..6918757
--- /dev/null
+++ b/ruoyi-message/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Sat Oct 10 14:15:13 CST 2026
+version=3.8.5
+groupId=com.ruoyi
+artifactId=ruoyi-message
diff --git a/ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..6108614
--- /dev/null
+++ b/ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,85 @@
+com\ruoyi\message\wechat\provider\xh\XinHuaMpApi.class
+com\ruoyi\message\sms\provider\ls\LishuiStaticConfig.class
+com\ruoyi\message\config\MessageConfigValidator.class
+com\ruoyi\message\MessageChannel.class
+com\ruoyi\message\sms\provider\sltd\ws\MessageSend.class
+com\ruoyi\message\wechat\WechatMpConfig.class
+com\ruoyi\message\sms\provider\ls\LishuiSmsSender.class
+com\ruoyi\message\wechat\provider\xh\XinHuaWXReq.class
+com\ruoyi\message\config\MessageProperties$Wechat.class
+com\ruoyi\message\config\MessageProperties.class
+com\ruoyi\message\sms\provider\shiyi\ShiyiSmsRequest.class
+com\ruoyi\message\wechat\support\WxMpUtils.class
+com\ruoyi\message\sms\AbstractSmsSender.class
+com\ruoyi\message\wechat\WechatSenderFactory.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GReportResponse.class
+com\ruoyi\message\sms\provider\aliyun\AliYunSmsSender$SendSmsRequestAdapter.class
+com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertSoap_PortType.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GSendResponse.class
+com\ruoyi\message\sms\provider\aliyun\AliYunSmsApi.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSVerifyPrivateResponse.class
+com\ruoyi\message\config\XhsmsConfig.class
+com\ruoyi\message\sms\provider\hzszlyy\ShiyiSmsApi.class
+com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsert.class
+com\ruoyi\message\sms\provider\shiyi\ShiyiHisSmsSender.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSSaveContent.class
+com\ruoyi\message\sms\provider\sltd\SltdResponseParser.class
+com\ruoyi\message\sms\provider\sltd\ws\SmsServiceSoap.class
+com\ruoyi\message\wechat\provider\hzszlyy\ShiyiMpApi.class
+com\ruoyi\message\wechat\WechatSender.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSGetUserListResponse.class
+com\ruoyi\message\sms\provider\sltd\ws\Hello.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GSearchNumber.class
+com\ruoyi\message\sms\provider\sltd\ws\HelloResponse.class
+com\ruoyi\message\SendException.class
+com\ruoyi\message\wechat\provider\sdk\WxMpSdkSender.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSVerify.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSGetUserList.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSGetTemplateListResponse.class
+com\ruoyi\message\sms\provider\ls\LishuiMessageConfigProvider.class
+com\ruoyi\message\sms\provider\xh\XinHuaSmsSender.class
+com\ruoyi\message\sms\SmsSendRequest.class
+com\ruoyi\message\sms\provider\messaginginsert\MessagingInsertSmsApi.class
+com\ruoyi\message\sms\provider\aliyun\AliYunSmsSender$1.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSVerifyPrivate.class
+com\ruoyi\message\sms\provider\shiyi\ShiyiSmsUtil.class
+com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertSoap_BindingStub.class
+com\ruoyi\message\sms\provider\shiyi\ShiyiSmsResponse.class
+com\ruoyi\message\SendResult.class
+com\ruoyi\message\sms\provider\sltd\ws\package-info.class
+com\ruoyi\message\wechat\WechatSendRequest.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSGetNumberResponse.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSSaveContentResponse.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSVerifyResponse.class
+com\ruoyi\message\config\MessageProperties$MessagingInsert.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GReply.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GSearchNumberResponse.class
+com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertSoap12Stub.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GSend.class
+com\ruoyi\message\sms\provider\aliyun\AliYunSmsSender.class
+com\ruoyi\message\config\AliyunSmsConfig.class
+com\ruoyi\message\config\RootMessageProperties.class
+com\ruoyi\message\wechat\WechatMpConfigProvider.class
+com\ruoyi\message\sms\provider\nhfy\MtSubmitSmUtil.class
+com\ruoyi\message\sms\provider\sltd\ws\SmsService.class
+com\ruoyi\message\sms\SmsSender.class
+com\ruoyi\message\config\MtSmsConfig.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GReport.class
+com\ruoyi\message\sms\provider\sltd\ws\ObjectFactory.class
+com\ruoyi\message\config\MessageProperties$Xinhua.class
+com\ruoyi\message\sms\provider\sltd\ws\I5GReplyResponse.class
+com\ruoyi\message\config\MessageProperties$ShiyiWechat.class
+com\ruoyi\message\config\MessageProperties$ShiyiSms.class
+com\ruoyi\message\sms\provider\nhfy\MtSubmitSmResp.class
+com\ruoyi\message\sms\provider\messaginginsert\MessagingInsertSmsSender.class
+com\ruoyi\message\config\MessageProperties$Sms.class
+com\ruoyi\message\wechat\provider\hzszlyy\ShiyiMpSender.class
+com\ruoyi\message\sms\provider\ls\LishuiMessageConfig.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSGetNumber.class
+com\ruoyi\message\sms\provider\sltd\ws\SMSGetTemplateList.class
+com\ruoyi\message\sms\provider\hzszlyy\ShiyiSmsSender.class
+com\ruoyi\message\sms\provider\nhfy\NhfySmsSender.class
+com\ruoyi\message\sms\provider\sltd\SltdSmsSender.class
+com\ruoyi\message\sms\SmsSenderFactory.class
+com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertLocator.class
+com\ruoyi\message\wechat\provider\xh\XinHuaMpSender.class
diff --git a/ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..edc46cd
--- /dev/null
+++ b/ruoyi-message/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,77 @@
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\config\XhsmsConfig.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\shiyi\ShiyiSmsUtil.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\Hello.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\SltdResponseParser.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\ObjectFactory.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\WechatMpConfigProvider.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\provider\hzszlyy\ShiyiMpApi.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\config\AliyunSmsConfig.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\shiyi\ShiyiSmsRequest.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSGetUserList.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\WechatSenderFactory.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\AbstractSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\config\MtSmsConfig.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSSaveContentResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSVerifyResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\config\RootMessageProperties.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\provider\xh\XinHuaWXReq.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\aliyun\AliYunSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\ls\LishuiSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertSoap_BindingStub.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\SltdSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\shiyi\ShiyiSmsResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSVerify.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\aliyun\AliYunSmsApi.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\messaginginsert\MessagingInsertSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSVerifyPrivate.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\MessageChannel.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\provider\sdk\WxMpSdkSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\provider\xh\XinHuaMpSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GReport.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\config\MessageConfigValidator.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertLocator.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\hzszlyy\ShiyiSmsApi.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GReplyResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\nhfy\MtSubmitSmUtil.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSGetTemplateListResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\SmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSVerifyPrivateResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\SmsSenderFactory.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertSoap12Stub.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSSaveContent.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\WechatSendRequest.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GSearchNumber.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSGetTemplateList.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\SmsSendRequest.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GSendResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSGetUserListResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\support\WxMpUtils.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\shiyi\ShiyiHisSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\xh\XinHuaSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\messaginginsert\MessagingInsertSmsApi.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\nhfy\MtSubmitSmResp.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GSend.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SmsService.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSGetNumberResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SmsServiceSoap.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\SendException.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\MessageSend.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\SMSGetNumber.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\package-info.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\HelloResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\WechatMpConfig.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsertSoap_PortType.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\messaginginsert\ws\MessagingInsert.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\hzszlyy\ShiyiSmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\provider\xh\XinHuaMpApi.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GReply.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\ls\LishuiMessageConfigProvider.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\config\MessageProperties.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GSearchNumberResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\ls\LishuiMessageConfig.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\nhfy\NhfySmsSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\sltd\ws\I5GReportResponse.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\WechatSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\sms\provider\ls\LishuiStaticConfig.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\wechat\provider\hzszlyy\ShiyiMpSender.java
+D:\daima\smartor\smartor\ruoyi-message\src\main\java\com\ruoyi\message\SendResult.java
diff --git a/ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
new file mode 100644
index 0000000..e673937
--- /dev/null
+++ b/ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst
@@ -0,0 +1,2 @@
+com\ruoyi\message\config\MessagePropertiesBindingCheck.class
+com\ruoyi\message\config\PerSiteBindingCheck.class
diff --git a/ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..6d77677
--- /dev/null
+++ b/ruoyi-message/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
@@ -0,0 +1,2 @@
+D:\daima\smartor\smartor\ruoyi-message\src\test\java\com\ruoyi\message\config\MessagePropertiesBindingCheck.java
+D:\daima\smartor\smartor\ruoyi-message\src\test\java\com\ruoyi\message\config\PerSiteBindingCheck.java
diff --git a/ruoyi-message/target/ruoyi-message-3.8.5.jar b/ruoyi-message/target/ruoyi-message-3.8.5.jar
new file mode 100644
index 0000000..402617f
--- /dev/null
+++ b/ruoyi-message/target/ruoyi-message-3.8.5.jar
Binary files differ
diff --git a/ruoyi-message/target/test-classes/com/ruoyi/message/config/MessagePropertiesBindingCheck.class b/ruoyi-message/target/test-classes/com/ruoyi/message/config/MessagePropertiesBindingCheck.class
new file mode 100644
index 0000000..1dc9362
--- /dev/null
+++ b/ruoyi-message/target/test-classes/com/ruoyi/message/config/MessagePropertiesBindingCheck.class
Binary files differ
diff --git a/ruoyi-message/target/test-classes/com/ruoyi/message/config/PerSiteBindingCheck.class b/ruoyi-message/target/test-classes/com/ruoyi/message/config/PerSiteBindingCheck.class
new file mode 100644
index 0000000..07edcd4
--- /dev/null
+++ b/ruoyi-message/target/test-classes/com/ruoyi/message/config/PerSiteBindingCheck.class
Binary files differ
diff --git a/ruoyi-message/target/test-classes/message-binding-check.yml b/ruoyi-message/target/test-classes/message-binding-check.yml
new file mode 100644
index 0000000..84d334a
--- /dev/null
+++ b/ruoyi-message/target/test-classes/message-binding-check.yml
@@ -0,0 +1,18 @@
+# 浠呯敤浜� MessagePropertiesBindingCheck锛氭ā鎷熷悇绔欑偣 application-<profile>.yml 鐨勩�屾牴绾ф墎骞� key銆�
+# 娉ㄦ剰锛氳繖浜� key 鍦ㄧ湡瀹為厤缃枃浠堕噷灏辨槸鏍圭骇鐨勶紝涓嶅甫浠讳綍鍓嶇紑
+xhsmsPath: http://192.16.4.220:8092/sendSms
+xhsmsAccount: 911124
+xhsmsPwd: zW5eXe
+xhsmsjrm: 1069055
+
+sms_accountName: S200232
+sms_password: lD94Yo
+sms_url: http://open.nhyfy.cn/kapi/gw-api/hntypt/ucpmsg/send
+sms_sourceAddr: 1069100020341
+sms_serviceCode: PUSH
+sms_appkey: ak-BFq4NN0TMf92J7KAioNYGz74
+sms_flag: 銆愬崡鍗庡ぇ瀛﹂檮灞炵涓�鍖婚櫌銆�
+
+accessKeyId: LTAI5tTestKeyId
+accessKeySecret: testSecret
+signName: 鏉窞鍒╂箹绉戞妧
diff --git a/ruoyi-quartz/pom.xml b/ruoyi-quartz/pom.xml
index 76091b2..238c697 100644
--- a/ruoyi-quartz/pom.xml
+++ b/ruoyi-quartz/pom.xml
@@ -44,6 +44,12 @@
             <version>3.8.5</version>
         </dependency>
 
+        <!-- 娑堟伅鍙戦�侊紙鐭俊/寰俊鍏紬鍙凤級妯″潡 -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-message</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
index 5a6cae9..2b0a141 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -11,13 +11,15 @@
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.core.service.IDingTalkService;
-import com.ruoyi.common.dx.MessageSend;
-import com.ruoyi.common.enums.MsgLSEnum;
 import com.ruoyi.common.enums.ServiceFromEnum;
-import com.ruoyi.common.enums.WxGZHEnum;
 import com.ruoyi.common.utils.*;
 import com.ruoyi.common.utils.http.HttpUtils;
-import com.ruoyi.common.utils.sms.smsUtils;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
+import com.ruoyi.message.sms.provider.xh.XinHuaSmsSender;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSenderFactory;
 import com.ruoyi.quartz.constant.MzGatherConstant;
 import com.ruoyi.quartz.enums.MzGatherParamEnum;
 import com.ruoyi.quartz.enums.MzGatherSlotEnum;
@@ -29,8 +31,7 @@
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysDeptService;
 import com.ruoyi.system.service.ISysUserService;
-import com.smartor.common.LSHospTokenUtil;
-import com.smartor.common.MtSubmitSmUtil;
+import com.ruoyi.message.sms.provider.sltd.ws.MessageSend;
 import com.smartor.common.QwenLLMUtil;
 import com.smartor.domain.*;
 import com.smartor.domain.VO.ServiceSubtaskDetailTraceVO;
@@ -49,7 +50,6 @@
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
-import java.security.MessageDigest;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
@@ -59,8 +59,6 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
-
-import static cn.hutool.core.convert.Convert.toHex;
 
 /**
  * 瀹氭椂浠诲姟璋冨害娴嬭瘯
@@ -122,18 +120,6 @@
     @Value("${localIP}")
     private String localIP;
 
-    @Value("${xhsmsPath}")
-    private String xhsmsPath;
-
-    @Value("${xhsmsAccount}")
-    private String xhsmsAccount;
-
-    @Value("${xhsmsPwd}")
-    private String xhsmsPwd;
-    // 铏氭嫙鎺ュ叆鐮�
-    @Value("${xhsmsjrm}")
-    private String xhsmsjrm;
-
     @Value("${pub_key}")
     private String pub_key;
 
@@ -192,8 +178,17 @@
     @Value("${server.port}")
     private String port;
 
+    /**
+     * 娑堟伅鍙戦�佹柟宸ュ巶锛堢煭淇�/寰俊鍏紬鍙凤級銆�
+     * <p>
+     * 鍘熸潵鐭俊涓庡叕浼楀彿鐨勫彂閫侀�昏緫鍦ㄦ湰绫婚噷鐢� {@code if (active.equals("xx"))} 纭垎鏀簡绾� 300 琛岋紝
+     * 鐜板凡鏀跺彛鍒� {@code ruoyi-message} 妯″潡锛岃繖閲屽彧璐熻矗鎸� {@code active} 璺敱銆�
+     */
     @Autowired
-    private MtSubmitSmUtil mtSubmitSmUtil;
+    private SmsSenderFactory smsSenderFactory;
+
+    @Autowired
+    private WechatSenderFactory wechatSenderFactory;
 
     @Value("${spring.profiles.active}")
     private String active;
@@ -1483,124 +1478,11 @@
                     serviceOutPath.setUpdateTime(new Date());
                     serviceOutPath.setUrl(url);
                     iServiceOutPathService.updateServiceOutPath(serviceOutPath);
-                    String isSuccess = null;
+                    //鐭俊鍙戦�侊細鍚勭珯鐐瑰鎺ユ柟寮忓樊寮傝緝澶э紙鎶ユ枃/绛惧悕/token/杩斿洖鍒ゅ畾閮戒笉鍚岋級锛�
+                    //宸叉敹鍙e埌 ruoyi-message 妯″潡锛岃繖閲屽彧璐熻矗缁勮鍏ュ弬骞惰矾鐢�
                     log.info("active鐨勫�间负锛歿}", active);
-                    if (active.equals("xh")) {
-                        Map<String, String> req = new HashMap<>();
-//                        req.put("phone", sendMagParam.getPhone());
-//                        req.put("content", sendMagParam.getContent());
-                        Map<String, String> map2 = new HashMap<String, String>();
-                        map2.put("action", "send");
-                        map2.put("account", xhsmsAccount);
-                        map2.put("password", xhsmsPwd);
-                        map2.put("mobile", sendMagParam.getPhone());
-                        map2.put("content", sendMagParam.getContent());
-                        map2.put("extno", xhsmsjrm);
-                        map2.put("rt", "json");
-                        StringBuilder encodedParams = new StringBuilder();
-
-                        for (Map.Entry<String, String> entry : map2.entrySet()) {
-                            if (encodedParams.length() > 0) {
-                                encodedParams.append("&");
-                            }
-                            // 瀵归敭鍜屽�艰繘琛孶RL缂栫爜
-                            String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
-                            String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
-                            encodedParams.append(encodedKey).append("=").append(encodedValue);
-                        }
-                        Boolean result = HttpUtils.sendPost(xhsmsPath, new Gson().toJson(req));
-                        if (result) isSuccess = "true";
-                    } else if (active.equals("ls")) {
-//                        String url = configService.selectConfigByKey("token.360", serviceSubtask.getOrgid());
-//                        //涓芥按鐨勭煭淇″彂閫佹柟寮�
-//                        Map<String, String> map = MsgLSEnum.getAddressByCode(serviceSubtask.getOrgid());
-                        SysConfig config = new SysConfig();
-                        config.setConfigKey("ls.msg.info");
-                        config.setOrgid(serviceSubtask.getOrgid());
-                        List<SysConfig> sysConfigs = configService.selectConfigList(config);
-                        Map<String, String> msgInfo = new HashMap<>();
-                        if (CollectionUtils.isNotEmpty(sysConfigs)) {
-                            String configValue = sysConfigs.get(0).getConfigValue();
-                            ObjectMapper objectMapper = new ObjectMapper();
-                            if (StringUtils.isNotEmpty(configValue)) {
-                                msgInfo = objectMapper.readValue(configValue, Map.class);
-                            }
-                        }
-                        log.info("-----------map鐨勫�间负锛歿}", msgInfo);
-                        String token = LSHospTokenUtil.getToken(serviceSubtask.getOrgid(), msgInfo.get("tokenUrl"));
-                        if (ObjectUtils.isNotEmpty(msgInfo) && StringUtils.isEmpty(msgInfo.get("address"))) {
-                            setSuccessPreachForm(serviceSubtask, sendPreachform, "鐭俊鍙戦�佸け璐�,璇ユ満鏋勬病鏈夐厤缃煭淇″湴鍧�, 鏃堕棿:" + now, "5");
-                            return;
-                        }
-                        log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫侊紝鍦板潃锛歿}锛屽弬鏁帮細{}锛屾満鏋処D锛歿}", msgInfo.get("address"), sendMagParam, serviceSubtask.getOrgid());
-                        String dxCode = getDXCode(msgInfo.get("address"), sendMagParam.getPhone(), sendMagParam.getContent(), msgInfo.get("sendPersonId"), msgInfo.get("sendPersonName"), MsgLSEnum.getHeaderByCode(msgInfo), token);
-                        log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫佺粨鏋滐細{}", dxCode);
-                        ObjectMapper objectMapper = new ObjectMapper();
-                        Map<String, Object> textParam = objectMapper.readValue(dxCode, Map.class);
-                        String code = textParam.get("Code").toString();
-                        if (code.equals("0")) {
-                            isSuccess = "true";
-                        }
-                    } else if (active.equals("sltd") || active.equals("nhfy")) {
-                        log.info("sltd杩涙潵浜嗗悧锛焮}   ,---sendMagParam.getContent()鐨勫弬鏁颁负锛歿}", active, sendMagParam.getContent());
-                        if (active.equals("sltd")) {
-                            //鐪佺珛鍚屽痉鐨勭煭淇″彂閫佹柟寮�
-                            String data = MessageSend.sendMsg(sendMagParam.getContent(), "6", sendMagParam.getPhone(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
-                            if (StringUtils.isNotEmpty(data)) {
-                                // 瑙f瀽 result=0&description=鎴愬姛&faillist= 鏍煎紡锛坮esult=0鎴愬姛锛�1澶辫触锛�
-                                log.info("銆恠fHandlle銆戠渷绔嬪悓寰风煭淇″彂閫佽繑鍥烇細{}", data);
-                                String[] pairs = data.split("&");
-                                String resultVal = null;
-                                for (String pair : pairs) {
-                                    String[] kv = pair.split("=", 2);
-                                    if ("result".equals(kv[0])) {
-                                        resultVal = kv.length > 1 ? kv[1] : null;
-                                        break;
-                                    }
-                                }
-                                if ("0".equals(resultVal)) {
-                                    isSuccess = "true";
-                                }
-                            }
-                        } else if (active.equals("nhfy")) {
-                            Map<String, Object> smsResult = mtSubmitSmUtil.submitSm(sendMagParam.getPhone(), sendMagParam.getContent());
-                            if (smsResult != null && smsResult.get("result") != null && smsResult.get("result").toString().equals("0")) {
-                                isSuccess = "true";
-                            }
-                        }
-                    } else if (active.equals("hzszlyy")) {//甯備竴鍖婚櫌
-                        String content = sendMagParam.getContent().replace("銆愭柊鍗庡尰闄€��", "");
-
-                        SysDept sysDeptVo = new SysDept();
-                        List<SysDept> sysDepts = new ArrayList<>();
-                        if (ObjectUtils.isNotEmpty(serviceSubtask.getDeptcode())) {
-                            sysDeptVo.setDeptType("1");
-                            sysDeptVo.setOrgid(serviceSubtask.getOrgid());
-                            sysDeptVo.setDeptCode(serviceSubtask.getDeptcode());
-                            sysDeptService.selectDeptList(sysDeptVo);
-                        } else if (ObjectUtils.isNotEmpty(serviceSubtask.getLeavehospitaldistrictcode())) {
-                            sysDeptVo.setDeptType("2");
-                            sysDeptVo.setOrgid(serviceSubtask.getOrgid());
-                            sysDeptVo.setDeptCode(serviceSubtask.getLeavehospitaldistrictcode());
-                            sysDeptService.selectDeptList(sysDeptVo);
-                        }
-                        SysDept sysDept = CollectionUtils.isNotEmpty(sysDepts) ? sysDepts.get(0) : new SysDept();
-                        String campusid = ObjectUtils.isNotEmpty(sysDept) ? sysDept.getCampusid() : "2";
-                        //婀栨花鍗曠嫭鍙戦�佹柟寮�
-                        if ("1".equals(campusid)) {
-                            String result = smsUtils.sendSms1(xhsmsPath, xhsmsAccount, xhsmsPwd, sendMagParam.getPhone(), content);
-                            //杩欓噷闇�瑕佹牴鎹畆esult杩斿洖鐨勫�煎幓鍒ゆ柇锛屾槸鍚︽垚鍔燂紝鐒跺悗灏嗗�艰祴鍊肩粰isSuccess
-                            if (StringUtils.isNotEmpty(result) && result.contains("澶勭悊鎴愬姛")) {
-                                isSuccess = "true";
-                            }
-                        } else {
-                            String result = smsUtils.sendSms(xhsmsPath, xhsmsAccount, xhsmsPwd, sendMagParam.getPhone(), content);
-                            //杩欓噷闇�瑕佹牴鎹畆esult杩斿洖鐨勫�煎幓鍒ゆ柇锛屾槸鍚︽垚鍔燂紝鐒跺悗灏嗗�艰祴鍊肩粰isSuccess
-                            if (StringUtils.isNotEmpty(result) && result.contains("澶勭悊鎴愬姛")) {
-                                isSuccess = "true";
-                            }
-                        }
-                    }
+                    SendResult smsSendResult = sendSmsByActive(serviceSubtask, sendMagParam);
+                    String isSuccess = smsSendResult.asLegacyFlag();
                     //浠诲姟鍙戦�佽褰�
                     ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                     serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
@@ -1659,29 +1541,11 @@
                     serviceOutPath.setUrl(url);
                     iServiceOutPathService.updateServiceOutPath(serviceOutPath);
 
-                    //鑾峰彇寰俊鍏紬鍙疯姹備俊鎭牴鎹満鏋処D
-                    List<String> wxqqxx = WxGZHEnum.getDescByCode(patArchive.getOrgid());
-                    //甯備竴鍖婚櫌 涓嶆牎楠�
+                    //寰俊鍏紬鍙峰彂閫侊細甯備竴涓庢柊鍗庢槸涓ゅ瀹屽叏涓嶅悓鐨勭綉鍏充笌鍒ゅ畾鏍囧噯锛�
+                    //鏈烘瀯閰嶇疆鏍¢獙銆丠IS鎮h�匢D鏍¢獙閮藉凡鏀跺彛鍒� ruoyi-message 鐨勫彂閫佹柟瀹炵幇閲�
+                    SendResult wechatSendResult = sendWechatByActive(serviceSubtask, patArchive, url);
+                    Boolean wxCodeSuccess = wechatSendResult.isOk();
 
-                    if (CollectionUtils.isEmpty(wxqqxx) || wxqqxx.size() < 4) {
-                        setSuccessPreachForm(serviceSubtask, sendPreachform, "銆愬叕浼楀彿銆戣鏈烘瀯鐨勫叕浼楀彿閰嶇疆淇℃伅涓嶅叏锛屾棤娉曢�氳繃鍏紬鍙峰彂閫�", "4");
-                        return;
-                    }
-
-                    if (StringUtils.isEmpty(patArchive.getPatidHis())) {
-                        setSuccessPreachForm(serviceSubtask, sendPreachform, "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�,his绯荤粺鐨勬偅鑰卛d涓虹┖", "5");
-                        return;
-                    }
-                    String wxCode = "";
-                    //甯備竴鍖婚櫌
-                    if (active.equals("hzszlyy")) {
-                        //澶勭悊涓枃涔辩爜闂
-                        wxCode = smsUtils.sendChat(url, patArchive.getTelcode(), serviceSubtask.getSfzh());
-                    } else {
-                        wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskDesc(), patArchive.getTelcode(), serviceSubtask.getSendname(), patArchive.getPatidHis(), wxqqxx);
-                    }
-
-                    Map map = JSONObject.parseObject(wxCode, Map.class);
                     //浠诲姟鍙戦�佽褰�
                     ServiceSubtaskRecord serviceSubtaskRecord = new ServiceSubtaskRecord();
                     serviceSubtaskRecord.setTaskid(serviceSubtask.getTaskid().toString());
@@ -1690,22 +1554,7 @@
                     serviceSubtaskRecord.setPreachform("4");
                     serviceSubtaskRecord.setStartTime(System.currentTimeMillis());
                     serviceSubtaskRecord.setResult("success");
-                    Boolean wxCodeSuccess = false;
-                    if (active.equals("hzszlyy")) {
-                        if (!map.isEmpty() && map.get("success") != null) {
-                            Integer wxCodeSuccessShiyi = (Integer) map.get("success");
-                            if (ObjectUtils.isNotEmpty(wxCodeSuccessShiyi) && wxCodeSuccessShiyi == 1) {
-                                wxCodeSuccess = true;
-                            } else {
-                                wxCodeSuccess = false;
-                            }
-                        }
-                    } else {
-                        if (!map.isEmpty() && map.get("succ") != null) {
-                            wxCodeSuccess = (boolean) map.get("succ");
-                        }
-                    }
-                    if (!map.isEmpty() && !wxCodeSuccess) serviceSubtaskRecord.setResult("error");
+                    if (!wxCodeSuccess) serviceSubtaskRecord.setResult("error");
                     serviceSubtaskRecordService.insertServiceSubtaskRecord(serviceSubtaskRecord);
 
                     //鍙戦�佸畬鎴愬悗锛屼慨鏀圭姸鎬�
@@ -1714,7 +1563,7 @@
                         serviceSubtask.setResult("success");
                         setSuccessPreachForm(serviceSubtask, sendPreachform, "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佹垚鍔�", "2");
                     } else {
-                        log.error("銆恠fHandlle銆戝叕浼楀彿鍙戦�佸け璐ワ紝鎮h�呬俊鎭細{}锛岄敊璇俊鎭細{}", serviceSubtask, map.get("msg"));
+                        log.error("銆恠fHandlle銆戝叕浼楀彿鍙戦�佸け璐ワ紝鎮h�呬俊鎭細{}锛岄敊璇俊鎭細{}", serviceSubtask, wechatSendResult.getMessage());
                         setSuccessPreachForm(serviceSubtask, sendPreachform, "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�", "5");
                     }
                 } catch (Exception e) {
@@ -1727,6 +1576,72 @@
             setSuccessPreachForm(serviceSubtask, sendPreachform, "浜哄伐鍙戦�佹垚鍔�", "2");
         }
 
+    }
+
+    /**
+     * 鎸� {@code active}锛堢珯鐐癸級璺敱鍒板搴旂殑鐭俊鍙戦�佹柟銆�
+     * <p>
+     * 鍚勭珯鐐瑰樊寮傝 {@code ruoyi-message} 妯″潡鍚勫疄鐜扮被锛涙湰鏂规硶鍙仛銆屽叆鍙傜粍瑁� + 璺敱 + 鏃ュ織銆嶃��
+     * <p>
+     * 鈿狅笍 鏂板崕锛坽@code xh}锛夌珯鐐逛粛璧般�屾棫瀹炵幇锛堝彂閫佺┖鎶ユ枃锛夈�嶏紝涓庡師 {@code RyTask} 琛屼负涓�瀛椾笉宸紝
+     * 纭缃戝叧鎶ユ枃鏍煎紡鍚庡簲鏀逛负 {@code XinHuaSmsSender#sendForm}銆傝瑙佽绫荤殑 TODO 璇存槑銆�
+     */
+    private SendResult sendSmsByActive(ServiceSubtask serviceSubtask, SendMagParam sendMagParam) {
+        SmsSendRequest request = SmsSendRequest.of(sendMagParam.getPhone(), sendMagParam.getContent(), serviceSubtask.getOrgid());
+        //甯備竴鍖哄垎婀栨花/鍚村北涓ゅ鐭俊绛惧悕
+        if ("hzszlyy".equals(active)) {
+            request.setCampus(resolveShiyiCampus(serviceSubtask));
+        }
+        if ("xh".equals(active)) {
+            XinHuaSmsSender xinHuaSmsSender = (XinHuaSmsSender) smsSenderFactory.get(active);
+            return xinHuaSmsSender.sendJsonLegacy(request);
+        }
+        return smsSenderFactory.send(active, request);
+    }
+
+    /**
+     * 鎸� {@code active}锛堢珯鐐癸級璺敱鍒板搴旂殑寰俊鍏紬鍙峰彂閫佹柟銆�
+     * <p>
+     * 鈿狅笍 鏂板崕鍏紬鍙峰繀椤讳紶鎮h�呬俊鎭紙濮撳悕 + HIS 鎮h�匢D锛夛紝涓庡師
+     * {@code getWXCode(...)} 鐨勫叆鍙備繚鎸佷竴涓�瀵瑰簲銆�
+     */
+    private SendResult sendWechatByActive(ServiceSubtask serviceSubtask, PatArchive patArchive, String url) {
+        WechatSendRequest request = new WechatSendRequest();
+        request.setOrgid(patArchive.getOrgid());
+        request.setIdCard(serviceSubtask.getSfzh());
+        request.setUrl(url);
+        request.setTitle(serviceSubtask.getTaskName());
+        request.setContent(serviceSubtask.getTaskDesc());
+        request.setPhone(patArchive.getTelcode());
+        request.setPatientName(serviceSubtask.getSendname());
+        request.setPatidHis(patArchive.getPatidHis());
+        return wechatSenderFactory.send(active, request);
+    }
+
+    /**
+     * 鏌ヨ鎮h�呮墍鍦ㄩ櫌鍖猴紙1=婀栨花锛屽叾浠�=鍚村北锛夈��
+     * <p>
+     * TODO 寰呯‘璁わ細鍘熷疄鐜板苟鏈妸 {@code sysDeptService.selectDeptList(...)} 鐨勮繑鍥炲�艰祴缁�
+     * {@code sysDepts}锛屽洜姝� {@code sysDepts} 鎭掍负绌哄垪琛ㄣ�亄@code campusid} 鎭掍负 {@code "2"}锛�
+     * 婀栨花闄㈠尯瀹為檯涓婃案杩滆蛋涓嶅埌 {@code sendSms1}銆傛湰娆¢噸鏋�<b>淇濇寔璇ヨ涓轰笉鍙�</b>锛�
+     * 璇峰湪涓氬姟纭鍚庡啀鍐冲畾鏄惁淇垚 {@code sysDepts = sysDeptService.selectDeptList(...)}銆�
+     */
+    private String resolveShiyiCampus(ServiceSubtask serviceSubtask) {
+        SysDept sysDeptVo = new SysDept();
+        List<SysDept> sysDepts = new ArrayList<>();
+        if (ObjectUtils.isNotEmpty(serviceSubtask.getDeptcode())) {
+            sysDeptVo.setDeptType("1");
+            sysDeptVo.setOrgid(serviceSubtask.getOrgid());
+            sysDeptVo.setDeptCode(serviceSubtask.getDeptcode());
+            sysDeptService.selectDeptList(sysDeptVo);
+        } else if (ObjectUtils.isNotEmpty(serviceSubtask.getLeavehospitaldistrictcode())) {
+            sysDeptVo.setDeptType("2");
+            sysDeptVo.setOrgid(serviceSubtask.getOrgid());
+            sysDeptVo.setDeptCode(serviceSubtask.getLeavehospitaldistrictcode());
+            sysDeptService.selectDeptList(sysDeptVo);
+        }
+        SysDept sysDept = CollectionUtils.isNotEmpty(sysDepts) ? sysDepts.get(0) : new SysDept();
+        return ObjectUtils.isNotEmpty(sysDept) ? sysDept.getCampusid() : "2";
     }
 
 
@@ -1863,74 +1778,10 @@
         return 0;
     }
 
-    private String getDXCode(String address, String ShouJiHM, String FaSongNR, String FaSongRID, String FaSongRXM, Map<String, Object> headerMap, String token) {
-        Map<String, Object> map = new LinkedHashMap<>();
-
-        Map<String, Object> YeWuXX = new LinkedHashMap<>();
-        Map<String, Object> DuanXinXX = new LinkedHashMap<>();
-        DuanXinXX.put("ShouJiHM", ShouJiHM);
-        DuanXinXX.put("FaSongNR", FaSongNR);
-        DuanXinXX.put("FaSongRID", FaSongRID);
-        DuanXinXX.put("FaSongRXM", FaSongRXM);
-        YeWuXX.put("DuanXinXX", DuanXinXX);
-
-        map.put("XiaoXiTou", headerMap);
-        map.put("YeWuXX", YeWuXX);
-
-        String body = new Gson().toJson(map);
-
-//        String result = HttpUtils.sendPost(address, body);
-        String result = null;
-        try {
-            result = OkHttpExample.sendPostRequest(address, body, token);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        log.info("銆恎etDXCode銆戠煭淇″彂閫佺粨鏋滐細{}", result);
-
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
-
-
-    private String getWXCode(String idcard, String url, String taskName, String taskDesc, String phone, String setPatientname, String setPatientid, List<String> wxqqxx) {
-        XinHuaWXReq xinHuaWXReq = new XinHuaWXReq();
-        xinHuaWXReq.setIdcard(idcard);
-        xinHuaWXReq.setUrl(url);
-        xinHuaWXReq.setPatientid(setPatientid);
-        xinHuaWXReq.setPatientname(setPatientname);
-        xinHuaWXReq.setMobile(phone);
-        xinHuaWXReq.setMedcardno(null);
-        xinHuaWXReq.setTitlename(taskName);
-        xinHuaWXReq.setContent(taskDesc);
-        xinHuaWXReq.setAppid(wxqqxx.get(1));
-        log.info("銆恎etWXCode銆戝井淇″叕浼楀彿璇锋眰鍙傛暟锛歿}", xinHuaWXReq);
-        String body = new Gson().toJson(xinHuaWXReq);
-        String encode = encode(wxqqxx.get(2).concat(body));
-        Map<String, String> headerMap = new HashMap<>();
-        headerMap.put("sign", encode);
-        String result = HttpUtils.sendPostByHeader(wxqqxx.get(3), body, headerMap);
-        log.info("銆恎etWXCode銆戝井淇″叕浼楀彿杩斿洖鍙傛暟锛歿}", result);
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
-
-
-    public String encode(String arg) {
-        if (arg == null) {
-            arg = "";
-        }
-        MessageDigest md5 = null;
-        try {
-            md5 = MessageDigest.getInstance("MD5");
-            md5.update(arg.getBytes("UTF-8"));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return toHex(md5.digest());
-    }
+    // ---------------------------------------------------------------------
+    // 璇存槑锛氬師 getDXCode / getWXCode / encode 涓変釜绉佹湁鏂规硶宸查殢鍙戦�佹柟涓�璧锋敹鍙e埌
+    // ruoyi-message 妯″潡锛圠ishuiSmsSender / XinHuaMpApi锛夛紝姝ゅ宸插垹闄わ紝閬垮厤閲嶅瀹炵幇銆�
+    // ---------------------------------------------------------------------
 
     public void collectHIS() {
         try {
diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml
index 4470c91..76448b6 100644
--- a/ruoyi-system/pom.xml
+++ b/ruoyi-system/pom.xml
@@ -23,6 +23,12 @@
             <artifactId>ruoyi-common</artifactId>
         </dependency>
 
+        <!-- 娑堟伅鍙戦�侊紙鐭俊/寰俊鍏紬鍙凤級妯″潡 -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-message</artifactId>
+        </dependency>
+
         <!-- WebService (鐭俊鍙戦��) -->
         <dependency>
             <groupId>org.apache.axis</groupId>
diff --git a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertTestCase.java b/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertTestCase.java
deleted file mode 100644
index 283acb2..0000000
--- a/ruoyi-system/src/main/java/WebServiceClient/MessagingInsertTestCase.java
+++ /dev/null
@@ -1,65 +0,0 @@
-///**
-// * MessagingInsertTestCase.java
-// * <p>
-// * This file was auto-generated from WSDL
-// * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
-// */
-//
-//package WebServiceClient;
-//
-//public class MessagingInsertTestCase extends junit.framework.TestCase {
-//    public MessagingInsertTestCase(String name) {
-//        super(name);
-//    }
-//
-//    public void testMessagingInsertSoap12WSDL() throws Exception {
-//        javax.xml.rpc.ServiceFactory serviceFactory = javax.xml.rpc.ServiceFactory.newInstance();
-//        java.net.URL url = new java.net.URL(new MessagingInsertLocator().getMessagingInsertSoap12Address() + "?WSDL");
-//        javax.xml.rpc.Service service = serviceFactory.createService(url, new MessagingInsertLocator().getServiceName());
-//        assertTrue(service != null);
-//    }
-//
-//    public void test1MessagingInsertSoap12SMSMessageAccept() throws Exception {
-//        MessagingInsertSoap12Stub binding;
-//        try {
-//            binding = (MessagingInsertSoap12Stub) new MessagingInsertLocator().getMessagingInsertSoap12();
-//        } catch (javax.xml.rpc.ServiceException jre) {
-//            if (jre.getLinkedCause() != null) jre.getLinkedCause().printStackTrace();
-//            throw new junit.framework.AssertionFailedError("JAX-RPC ServiceException caught: " + jre);
-//        }
-//        assertNotNull("binding is null", binding);
-//
-//        // Time out after a minute
-//        binding.setTimeout(60000);
-//
-//        // Test operation
-//        binding.SMSMessageAccept(new String(), new javax.xml.rpc.holders.IntHolder(), new javax.xml.rpc.holders.StringHolder());
-//        // TBD - validate results
-//    }
-//
-//    public void testMessagingInsertSoapWSDL() throws Exception {
-//        javax.xml.rpc.ServiceFactory serviceFactory = javax.xml.rpc.ServiceFactory.newInstance();
-//        java.net.URL url = new java.net.URL(new MessagingInsertLocator().getMessagingInsertSoapAddress() + "?WSDL");
-//        javax.xml.rpc.Service service = serviceFactory.createService(url, new MessagingInsertLocator().getServiceName());
-//        assertTrue(service != null);
-//    }
-//
-//    public void test2MessagingInsertSoapSMSMessageAccept() throws Exception {
-//        MessagingInsertSoap_BindingStub binding;
-//        try {
-//            binding = (MessagingInsertSoap_BindingStub) new MessagingInsertLocator().getMessagingInsertSoap();
-//        } catch (javax.xml.rpc.ServiceException jre) {
-//            if (jre.getLinkedCause() != null) jre.getLinkedCause().printStackTrace();
-//            throw new junit.framework.AssertionFailedError("JAX-RPC ServiceException caught: " + jre);
-//        }
-//        assertNotNull("binding is null", binding);
-//
-//        // Time out after a minute
-//        binding.setTimeout(60000);
-//
-//        // Test operation
-//        binding.SMSMessageAccept(new String(), new javax.xml.rpc.holders.IntHolder(), new javax.xml.rpc.holders.StringHolder());
-//        // TBD - validate results
-//    }
-//
-//}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsParamServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsParamServiceImpl.java
index aa70c84..0e29e7d 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsParamServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsParamServiceImpl.java
@@ -1,17 +1,13 @@
 package com.ruoyi.system.service.impl;
 
-import WebServiceClient.MessagingInsertLocator;
-import WebServiceClient.MessagingInsertSoap12Stub;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.message.sms.provider.messaginginsert.MessagingInsertSmsApi;
 import com.ruoyi.system.domain.SmsParam;
 import com.ruoyi.system.mapper.SmsParamMapper;
 import com.ruoyi.system.service.ISmsParamService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import javax.xml.rpc.holders.IntHolder;
-import java.rmi.RemoteException;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -24,6 +20,12 @@
 public class SmsParamServiceImpl implements ISmsParamService {
     @Autowired
     private SmsParamMapper smsParamMapper;
+
+    /**
+     * 棰勭害鎸傚彿鐭俊骞冲彴锛圡essagingInsert锛堿PI锛屽凡鏀跺彛鍒� ruoyi-message 妯″潡
+     */
+    @Autowired
+    private MessagingInsertSmsApi messagingInsertSmsApi;
 
     /**
      * 鏌ヨ鐭俊鍙傛暟
@@ -96,19 +98,8 @@
 
     @Override
     public int sendSmsInfo(String info, String phone) {
-        MessagingInsertSoap12Stub binding = null;
-        try {
-            binding = (MessagingInsertSoap12Stub) new MessagingInsertLocator().getMessagingInsertSoap12();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        String aa = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<Request>\n" + "<operate>S001</operate>\n" + "<Sheets>\n" + "<Sheet>\n" + "<Content>" + info + "</Content>\n" + "<Mobile>" + phone + "</Mobile>\n" + "<DateTime>" + new Date() + "</DateTime>\n" + "<Type>棰勭害鎸傚彿</Type>\n" + "</Sheet>\n" + "</Sheets>\n" + "</Request>";
-        Integer integer = null;
-        try {
-            integer = binding.SMSMessageAccept(aa, new IntHolder(), new javax.xml.rpc.holders.StringHolder());
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-        return integer;
+        //棰勭害鎸傚彿鐭俊骞冲彴锛圡essagingInsert锛孉xis SOAP12锛夊凡鏀跺彛鍒� ruoyi-message 妯″潡
+        Integer result = messagingInsertSmsApi.sendSmsInfo(info, phone);
+        return result == null ? 0 : result;
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsRecordsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsRecordsServiceImpl.java
index 1aad224..cf899c0 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsRecordsServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SmsRecordsServiceImpl.java
@@ -1,25 +1,18 @@
 package com.ruoyi.system.service.impl;
 
-import java.io.IOException;
 import java.sql.Date;
 import java.time.LocalDate;
 import java.util.*;
 
-import com.alibaba.fastjson2.JSONObject;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.gson.Gson;
-import com.ruoyi.common.enums.MsgLSEnum;
 import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.OkHttpExample;
 import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.system.domain.SysConfig;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.common.core.service.ISubtaskSmsService;
 import com.ruoyi.common.utils.spring.SpringUtils;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.system.mapper.SmsRecordsMapper;
@@ -41,8 +34,11 @@
     @Autowired
     private ISysConfigService iSysConfigService;
 
+    /**
+     * 娑堟伅鍙戦�佹柟宸ュ巶锛堢煭淇★級锛屼附姘寸煭淇″凡鏀跺彛鍒� ruoyi-message
+     */
     @Autowired
-    private ISysConfigService configService;
+    private SmsSenderFactory smsSenderFactory;
     /**
      * 鏌ヨ鐭俊璁板綍
      *
@@ -116,39 +112,18 @@
 
 
     public Boolean sendSMS(String orgid, String phone, String content) {
-        //涓芥按鐨勭煭淇″彂閫佹柟寮�
-        Boolean isSuccess = false;
+        //涓芥按鐨勭煭淇″彂閫佹柟寮忥細宸叉敹鍙e埌 ruoyi-message 鐨� LishuiSmsSender
+        //锛堟満鏋勯厤缃粠 sys_config 鐨� ls.msg.info 璇诲彇锛宼oken 鐢� smartor 娉ㄥ唽鐨�
+        //  LishuiMessageConfigProvider 鎻愪緵锛夛紝杩欓噷涓嶅啀鑷繁鎷兼姤鏂�
         try {
-            SysConfig config = new SysConfig();
-            config.setConfigKey("ls.msg.info");
-            config.setOrgid(orgid);
-            List<SysConfig> sysConfigs = configService.selectConfigList(config);
-            Map<String, String> msgInfo = new HashMap<>();
-            if (CollectionUtils.isNotEmpty(sysConfigs)) {
-                String configValue = sysConfigs.get(0).getConfigValue();
-                ObjectMapper objectMapper = new ObjectMapper();
-                if (StringUtils.isNotEmpty(configValue)) {
-                    msgInfo = objectMapper.readValue(configValue, Map.class);
-                }
-            }
-            log.info("-----------map鐨勫�间负锛歿}", msgInfo);
-
-            ISubtaskSmsService subtaskSmsService = SpringUtils.getBean(ISubtaskSmsService.class);
-            String token = subtaskSmsService.getLSHospToken(orgid, msgInfo.get("tokenUrl"));
-            log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫侊紝鍦板潃锛歿}锛屽弬鏁帮細{}锛屾満鏋処D锛歿}", msgInfo.get("address"), orgid);
-            String dxCode = getDXCode(msgInfo.get("address"), phone, content, msgInfo.get("sendPersonId"), msgInfo.get("sendPersonName"), MsgLSEnum.getHeaderByCode(msgInfo), token);
-            log.info("銆恠fHandlle銆戜附姘寸煭淇″彂閫佺粨鏋滐細{}", dxCode);
-            ObjectMapper objectMapper = new ObjectMapper();
-            Map<String, Object> textParam = null;
-            textParam = objectMapper.readValue(dxCode, Map.class);
-            String code = textParam.get("Code").toString();
-            if (code.equals("0")) {
-                isSuccess = true;
-            }
+            SendResult sendResult = smsSenderFactory.send("ls",
+                    SmsSendRequest.of(phone, content, orgid));
+            log.info("銆怱msRecordsServiceImpl銆戜附姘寸煭淇″彂閫佺粨鏋滐細{}", sendResult);
+            return sendResult.isOk();
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error("銆怱msRecordsServiceImpl銆戜附姘寸煭淇″彂閫佸紓甯革紝orgid锛歿}锛宲hone锛歿}", orgid, phone, e);
+            return false;
         }
-        return isSuccess;
     }
 
     /**
@@ -162,7 +137,6 @@
         smsRecords.setUpdateTime(DateUtils.getNowDate());
         return smsRecordsMapper.updateSmsRecords(smsRecords);
     }
-
     /**
      * 鎵归噺鍒犻櫎鐭俊璁板綍
      *
@@ -185,34 +159,8 @@
         return smsRecordsMapper.deleteSmsRecordsByRecordid(recordid);
     }
 
-
-    private String getDXCode(String address, String ShouJiHM, String FaSongNR, String FaSongRID, String FaSongRXM, Map<String, Object> headerMap, String token) {
-        Map<String, Object> map = new LinkedHashMap<>();
-
-        Map<String, Object> YeWuXX = new LinkedHashMap<>();
-        Map<String, Object> DuanXinXX = new LinkedHashMap<>();
-        DuanXinXX.put("ShouJiHM", ShouJiHM);
-        DuanXinXX.put("FaSongNR", FaSongNR);
-        DuanXinXX.put("FaSongRID", FaSongRID);
-        DuanXinXX.put("FaSongRXM", FaSongRXM);
-        YeWuXX.put("DuanXinXX", DuanXinXX);
-
-        map.put("XiaoXiTou", headerMap);
-        map.put("YeWuXX", YeWuXX);
-
-        String body = new Gson().toJson(map);
-
-//        String result = HttpUtils.sendPost(address, body);
-        String result = null;
-        try {
-            result = OkHttpExample.sendPostRequest(address, body, token);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        log.info("銆恎etDXCode銆戠煭淇″彂閫佺粨鏋滐細{}", result);
-
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
+    // ---------------------------------------------------------------------
+    // 璇存槑锛氬師 getDXCode 宸查殢鍙戦�佹柟涓�璧锋敹鍙e埌 ruoyi-message 鐨� LishuiSmsSender锛�
+    // 姝ゅ宸插垹闄わ紝閬垮厤绗笁濂椾附姘存姤鏂囧疄鐜扮户缁瓨鍦ㄣ��
+    // ---------------------------------------------------------------------
 }
diff --git a/smartor/pom.xml b/smartor/pom.xml
index f257b5e..6bac502 100644
--- a/smartor/pom.xml
+++ b/smartor/pom.xml
@@ -155,6 +155,11 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-system</artifactId>
         </dependency>
+        <!-- 娑堟伅鍙戦�侊紙鐭俊/寰俊鍏紬鍙凤級妯″潡 -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-message</artifactId>
+        </dependency>
     </dependencies>
 
 
diff --git a/smartor/src/main/java/WebServiceClient/MessagingInsert.asmx b/smartor/src/main/java/WebServiceClient/MessagingInsert.asmx
deleted file mode 100644
index 423cb09..0000000
--- a/smartor/src/main/java/WebServiceClient/MessagingInsert.asmx
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
-  <wsdl:types>
-    <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
-      <s:element name="SMSMessageAccept">
-        <s:complexType>
-          <s:sequence>
-            <s:element minOccurs="0" maxOccurs="1" name="xmlReq" type="s:string" />
-          </s:sequence>
-        </s:complexType>
-      </s:element>
-      <s:element name="SMSMessageAcceptResponse">
-        <s:complexType>
-          <s:sequence>
-            <s:element minOccurs="1" maxOccurs="1" name="SMSMessageAcceptResult" type="s:int" />
-            <s:element minOccurs="0" maxOccurs="1" name="xmlResp" type="s:string" />
-          </s:sequence>
-        </s:complexType>
-      </s:element>
-    </s:schema>
-  </wsdl:types>
-  <wsdl:message name="SMSMessageAcceptSoapIn">
-    <wsdl:part name="parameters" element="tns:SMSMessageAccept" />
-  </wsdl:message>
-  <wsdl:message name="SMSMessageAcceptSoapOut">
-    <wsdl:part name="parameters" element="tns:SMSMessageAcceptResponse" />
-  </wsdl:message>
-  <wsdl:portType name="MessagingInsertSoap">
-    <wsdl:operation name="SMSMessageAccept">
-      <wsdl:input message="tns:SMSMessageAcceptSoapIn" />
-      <wsdl:output message="tns:SMSMessageAcceptSoapOut" />
-    </wsdl:operation>
-  </wsdl:portType>
-  <wsdl:binding name="MessagingInsertSoap" type="tns:MessagingInsertSoap">
-    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
-    <wsdl:operation name="SMSMessageAccept">
-      <soap:operation soapAction="http://tempuri.org/SMSMessageAccept" style="document" />
-      <wsdl:input>
-        <soap:body use="literal" />
-      </wsdl:input>
-      <wsdl:output>
-        <soap:body use="literal" />
-      </wsdl:output>
-    </wsdl:operation>
-  </wsdl:binding>
-  <wsdl:binding name="MessagingInsertSoap12" type="tns:MessagingInsertSoap">
-    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
-    <wsdl:operation name="SMSMessageAccept">
-      <soap12:operation soapAction="http://tempuri.org/SMSMessageAccept" style="document" />
-      <wsdl:input>
-        <soap12:body use="literal" />
-      </wsdl:input>
-      <wsdl:output>
-        <soap12:body use="literal" />
-      </wsdl:output>
-    </wsdl:operation>
-  </wsdl:binding>
-  <wsdl:service name="MessagingInsert">
-    <wsdl:port name="MessagingInsertSoap" binding="tns:MessagingInsertSoap">
-      <soap:address location="http://218.108.11.29:8081/MessagingInsert.asmx" />
-    </wsdl:port>
-    <wsdl:port name="MessagingInsertSoap12" binding="tns:MessagingInsertSoap12">
-      <soap12:address location="http://218.108.11.29:8081/MessagingInsert.asmx" />
-    </wsdl:port>
-  </wsdl:service>
-</wsdl:definitions>
\ No newline at end of file
diff --git a/smartor/src/main/java/WebServiceClient/MessagingInsert.java b/smartor/src/main/java/WebServiceClient/MessagingInsert.java
deleted file mode 100644
index bf446d3..0000000
--- a/smartor/src/main/java/WebServiceClient/MessagingInsert.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * MessagingInsert.java
- *
- * This file was auto-generated from WSDL
- * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
- */
-
-package WebServiceClient;
-
-public interface MessagingInsert extends javax.xml.rpc.Service {
-    public String getMessagingInsertSoap12Address();
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap12() throws javax.xml.rpc.ServiceException;
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap12(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
-    public String getMessagingInsertSoapAddress();
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap() throws javax.xml.rpc.ServiceException;
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
-}
diff --git a/smartor/src/main/java/WebServiceClient/MessagingInsertLocator.java b/smartor/src/main/java/WebServiceClient/MessagingInsertLocator.java
deleted file mode 100644
index 2c52b13..0000000
--- a/smartor/src/main/java/WebServiceClient/MessagingInsertLocator.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * MessagingInsertLocator.java
- *
- * This file was auto-generated from WSDL
- * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
- */
-
-package WebServiceClient;
-
-public class MessagingInsertLocator extends org.apache.axis.client.Service implements MessagingInsert {
-
-    public MessagingInsertLocator() {
-    }
-
-
-    public MessagingInsertLocator(org.apache.axis.EngineConfiguration config) {
-        super(config);
-    }
-
-    public MessagingInsertLocator(String wsdlLoc, javax.xml.namespace.QName sName) throws javax.xml.rpc.ServiceException {
-        super(wsdlLoc, sName);
-    }
-
-    // Use to get a proxy class for MessagingInsertSoap12
-    private String MessagingInsertSoap12_address = "http://218.108.11.29:8081/MessagingInsert.asmx";
-
-    public String getMessagingInsertSoap12Address() {
-        return MessagingInsertSoap12_address;
-    }
-
-    // The WSDD service name defaults to the port name.
-    private String MessagingInsertSoap12WSDDServiceName = "MessagingInsertSoap12";
-
-    public String getMessagingInsertSoap12WSDDServiceName() {
-        return MessagingInsertSoap12WSDDServiceName;
-    }
-
-    public void setMessagingInsertSoap12WSDDServiceName(String name) {
-        MessagingInsertSoap12WSDDServiceName = name;
-    }
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap12() throws javax.xml.rpc.ServiceException {
-       java.net.URL endpoint;
-        try {
-            endpoint = new java.net.URL(MessagingInsertSoap12_address);
-        }
-        catch (java.net.MalformedURLException e) {
-            throw new javax.xml.rpc.ServiceException(e);
-        }
-        return getMessagingInsertSoap12(endpoint);
-    }
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap12(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
-        try {
-            MessagingInsertSoap12Stub _stub = new MessagingInsertSoap12Stub(portAddress, this);
-            _stub.setPortName(getMessagingInsertSoap12WSDDServiceName());
-            return _stub;
-        }
-        catch (org.apache.axis.AxisFault e) {
-            return null;
-        }
-    }
-
-    public void setMessagingInsertSoap12EndpointAddress(String address) {
-        MessagingInsertSoap12_address = address;
-    }
-
-
-    // Use to get a proxy class for MessagingInsertSoap
-    private String MessagingInsertSoap_address = "http://218.108.11.29:8081/MessagingInsert.asmx";
-
-    public String getMessagingInsertSoapAddress() {
-        return MessagingInsertSoap_address;
-    }
-
-    // The WSDD service name defaults to the port name.
-    private String MessagingInsertSoapWSDDServiceName = "MessagingInsertSoap";
-
-    public String getMessagingInsertSoapWSDDServiceName() {
-        return MessagingInsertSoapWSDDServiceName;
-    }
-
-    public void setMessagingInsertSoapWSDDServiceName(String name) {
-        MessagingInsertSoapWSDDServiceName = name;
-    }
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap() throws javax.xml.rpc.ServiceException {
-       java.net.URL endpoint;
-        try {
-            endpoint = new java.net.URL(MessagingInsertSoap_address);
-        }
-        catch (java.net.MalformedURLException e) {
-            throw new javax.xml.rpc.ServiceException(e);
-        }
-        return getMessagingInsertSoap(endpoint);
-    }
-
-    public MessagingInsertSoap_PortType getMessagingInsertSoap(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
-        try {
-            MessagingInsertSoap_BindingStub _stub = new MessagingInsertSoap_BindingStub(portAddress, this);
-            _stub.setPortName(getMessagingInsertSoapWSDDServiceName());
-            return _stub;
-        }
-        catch (org.apache.axis.AxisFault e) {
-            return null;
-        }
-    }
-
-    public void setMessagingInsertSoapEndpointAddress(String address) {
-        MessagingInsertSoap_address = address;
-    }
-
-    /**
-     * For the given interface, get the stub implementation.
-     * If this service has no port for the given interface,
-     * then ServiceException is thrown.
-     * This service has multiple ports for a given interface;
-     * the proxy implementation returned may be indeterminate.
-     */
-    public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
-        try {
-            if (MessagingInsertSoap_PortType.class.isAssignableFrom(serviceEndpointInterface)) {
-                MessagingInsertSoap12Stub _stub = new MessagingInsertSoap12Stub(new java.net.URL(MessagingInsertSoap12_address), this);
-                _stub.setPortName(getMessagingInsertSoap12WSDDServiceName());
-                return _stub;
-            }
-            if (MessagingInsertSoap_PortType.class.isAssignableFrom(serviceEndpointInterface)) {
-                MessagingInsertSoap_BindingStub _stub = new MessagingInsertSoap_BindingStub(new java.net.URL(MessagingInsertSoap_address), this);
-                _stub.setPortName(getMessagingInsertSoapWSDDServiceName());
-                return _stub;
-            }
-        }
-        catch (Throwable t) {
-            throw new javax.xml.rpc.ServiceException(t);
-        }
-        throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface:  " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName()));
-    }
-
-    /**
-     * For the given interface, get the stub implementation.
-     * If this service has no port for the given interface,
-     * then ServiceException is thrown.
-     */
-    public java.rmi.Remote getPort(javax.xml.namespace.QName portName, Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
-        if (portName == null) {
-            return getPort(serviceEndpointInterface);
-        }
-        String inputPortName = portName.getLocalPart();
-        if ("MessagingInsertSoap12".equals(inputPortName)) {
-            return getMessagingInsertSoap12();
-        }
-        else if ("MessagingInsertSoap".equals(inputPortName)) {
-            return getMessagingInsertSoap();
-        }
-        else  {
-            java.rmi.Remote _stub = getPort(serviceEndpointInterface);
-            ((org.apache.axis.client.Stub) _stub).setPortName(portName);
-            return _stub;
-        }
-    }
-
-    public javax.xml.namespace.QName getServiceName() {
-        return new javax.xml.namespace.QName("http://tempuri.org/", "MessagingInsert");
-    }
-
-    private java.util.HashSet ports = null;
-
-    public java.util.Iterator getPorts() {
-        if (ports == null) {
-            ports = new java.util.HashSet();
-            ports.add(new javax.xml.namespace.QName("http://tempuri.org/", "MessagingInsertSoap12"));
-            ports.add(new javax.xml.namespace.QName("http://tempuri.org/", "MessagingInsertSoap"));
-        }
-        return ports.iterator();
-    }
-
-    /**
-    * Set the endpoint address for the specified port name.
-    */
-    public void setEndpointAddress(String portName, String address) throws javax.xml.rpc.ServiceException {
-
-if ("MessagingInsertSoap12".equals(portName)) {
-            setMessagingInsertSoap12EndpointAddress(address);
-        }
-        else
-if ("MessagingInsertSoap".equals(portName)) {
-            setMessagingInsertSoapEndpointAddress(address);
-        }
-        else
-{ // Unknown Port Name
-            throw new javax.xml.rpc.ServiceException(" Cannot set Endpoint Address for Unknown Port" + portName);
-        }
-    }
-
-    /**
-    * Set the endpoint address for the specified port name.
-    */
-    public void setEndpointAddress(javax.xml.namespace.QName portName, String address) throws javax.xml.rpc.ServiceException {
-        setEndpointAddress(portName.getLocalPart(), address);
-    }
-
-}
diff --git a/smartor/src/main/java/WebServiceClient/MessagingInsertSoap12Stub.java b/smartor/src/main/java/WebServiceClient/MessagingInsertSoap12Stub.java
deleted file mode 100644
index 496334e..0000000
--- a/smartor/src/main/java/WebServiceClient/MessagingInsertSoap12Stub.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * MessagingInsertSoap12Stub.java
- * <p>
- * This file was auto-generated from WSDL
- * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
- */
-
-package WebServiceClient;
-
-public class MessagingInsertSoap12Stub extends org.apache.axis.client.Stub implements MessagingInsertSoap_PortType {
-    private java.util.Vector cachedSerClasses = new java.util.Vector();
-    private java.util.Vector cachedSerQNames = new java.util.Vector();
-    private java.util.Vector cachedSerFactories = new java.util.Vector();
-    private java.util.Vector cachedDeserFactories = new java.util.Vector();
-
-    static org.apache.axis.description.OperationDesc[] _operations;
-
-    static {
-        _operations = new org.apache.axis.description.OperationDesc[1];
-        _initOperationDesc1();
-    }
-
-    private static void _initOperationDesc1() {
-        org.apache.axis.description.OperationDesc oper;
-        org.apache.axis.description.ParameterDesc param;
-        oper = new org.apache.axis.description.OperationDesc();
-        oper.setName("SMSMessageAccept");
-        param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("http://tempuri.org/", "xmlReq"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), String.class, false, false);
-        param.setOmittable(true);
-        oper.addParameter(param);
-        param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAcceptResult"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int"), int.class, false, false);
-        oper.addParameter(param);
-        param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("http://tempuri.org/", "xmlResp"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), String.class, false, false);
-        param.setOmittable(true);
-        oper.addParameter(param);
-        oper.setReturnType(org.apache.axis.encoding.XMLType.AXIS_VOID);
-        oper.setStyle(org.apache.axis.constants.Style.WRAPPED);
-        oper.setUse(org.apache.axis.constants.Use.LITERAL);
-        _operations[0] = oper;
-
-    }
-
-    public MessagingInsertSoap12Stub() throws org.apache.axis.AxisFault {
-        this(null);
-    }
-
-    public MessagingInsertSoap12Stub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
-        this(service);
-        super.cachedEndpoint = endpointURL;
-    }
-
-    public MessagingInsertSoap12Stub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
-        if (service == null) {
-            super.service = new org.apache.axis.client.Service();
-        } else {
-            super.service = service;
-        }
-        ((org.apache.axis.client.Service) super.service).setTypeMappingVersion("1.1");
-    }
-
-    protected org.apache.axis.client.Call createCall() throws java.rmi.RemoteException {
-        try {
-            org.apache.axis.client.Call _call = super._createCall();
-            if (super.maintainSessionSet) {
-                _call.setMaintainSession(super.maintainSession);
-            }
-            if (super.cachedUsername != null) {
-                _call.setUsername(super.cachedUsername);
-            }
-            if (super.cachedPassword != null) {
-                _call.setPassword(super.cachedPassword);
-            }
-            if (super.cachedEndpoint != null) {
-                _call.setTargetEndpointAddress(super.cachedEndpoint);
-            }
-            if (super.cachedTimeout != null) {
-                _call.setTimeout(super.cachedTimeout);
-            }
-            if (super.cachedPortName != null) {
-                _call.setPortName(super.cachedPortName);
-            }
-            java.util.Enumeration keys = super.cachedProperties.keys();
-            while (keys.hasMoreElements()) {
-                String key = (String) keys.nextElement();
-                _call.setProperty(key, super.cachedProperties.get(key));
-            }
-            return _call;
-        } catch (Throwable _t) {
-            throw new org.apache.axis.AxisFault("Failure trying to get the Call object", _t);
-        }
-    }
-
-    public Integer SMSMessageAccept(String xmlReq, javax.xml.rpc.holders.IntHolder SMSMessageAcceptResult, javax.xml.rpc.holders.StringHolder xmlResp) throws java.rmi.RemoteException {
-        Integer success = null;
-        if (super.cachedEndpoint == null) {
-            throw new org.apache.axis.NoEndPointException();
-        }
-        org.apache.axis.client.Call _call = createCall();
-        _call.setOperation(_operations[0]);
-        _call.setUseSOAPAction(true);
-        _call.setSOAPActionURI("http://tempuri.org/SMSMessageAccept");
-        _call.setEncodingStyle(null);
-        _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
-        _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
-        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP12_CONSTANTS);
-        _call.setOperationName(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAccept"));
-
-        setRequestHeaders(_call);
-        setAttachments(_call);
-        try {
-            Object _resp = _call.invoke(new Object[]{xmlReq});
-
-            if (_resp instanceof java.rmi.RemoteException) {
-                throw (java.rmi.RemoteException) _resp;
-            } else {
-                extractAttachments(_call);
-                java.util.Map _output;
-                _output = _call.getOutputParams();
-                try {
-                    success = ((Integer) _output.get(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAcceptResult"))).intValue();
-                } catch (Exception _exception) {
-                    success = ((Integer) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAcceptResult")), int.class)).intValue();
-                }
-                try {
-                    xmlResp.value = (String) _output.get(new javax.xml.namespace.QName("http://tempuri.org/", "xmlResp"));
-                } catch (Exception _exception) {
-                    xmlResp.value = (String) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://tempuri.org/", "xmlResp")), String.class);
-                }
-            }
-        } catch (org.apache.axis.AxisFault axisFaultException) {
-            throw axisFaultException;
-        }
-        return success;
-    }
-
-}
diff --git a/smartor/src/main/java/WebServiceClient/MessagingInsertSoap_BindingStub.java b/smartor/src/main/java/WebServiceClient/MessagingInsertSoap_BindingStub.java
deleted file mode 100644
index 1d6f833..0000000
--- a/smartor/src/main/java/WebServiceClient/MessagingInsertSoap_BindingStub.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * MessagingInsertSoap_BindingStub.java
- * <p>
- * This file was auto-generated from WSDL
- * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
- */
-
-package WebServiceClient;
-
-import org.apache.axis.client.Stub;
-
-public class MessagingInsertSoap_BindingStub extends Stub implements MessagingInsertSoap_PortType {
-    private java.util.Vector cachedSerClasses = new java.util.Vector();
-    private java.util.Vector cachedSerQNames = new java.util.Vector();
-    private java.util.Vector cachedSerFactories = new java.util.Vector();
-    private java.util.Vector cachedDeserFactories = new java.util.Vector();
-
-    static org.apache.axis.description.OperationDesc[] _operations;
-
-    static {
-        _operations = new org.apache.axis.description.OperationDesc[1];
-        _initOperationDesc1();
-    }
-
-    private static void _initOperationDesc1() {
-        org.apache.axis.description.OperationDesc oper;
-        org.apache.axis.description.ParameterDesc param;
-        oper = new org.apache.axis.description.OperationDesc();
-        oper.setName("SMSMessageAccept");
-        param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("http://tempuri.org/", "xmlReq"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), String.class, false, false);
-        param.setOmittable(true);
-        oper.addParameter(param);
-        param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAcceptResult"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int"), int.class, false, false);
-        oper.addParameter(param);
-        param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("http://tempuri.org/", "xmlResp"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), String.class, false, false);
-        param.setOmittable(true);
-        oper.addParameter(param);
-        oper.setReturnType(org.apache.axis.encoding.XMLType.AXIS_VOID);
-        oper.setStyle(org.apache.axis.constants.Style.WRAPPED);
-        oper.setUse(org.apache.axis.constants.Use.LITERAL);
-        _operations[0] = oper;
-
-    }
-
-    public MessagingInsertSoap_BindingStub() throws org.apache.axis.AxisFault {
-        this(null);
-    }
-
-    public MessagingInsertSoap_BindingStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
-        this(service);
-        super.cachedEndpoint = endpointURL;
-    }
-
-    public MessagingInsertSoap_BindingStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
-        if (service == null) {
-            super.service = new org.apache.axis.client.Service();
-        } else {
-            super.service = service;
-        }
-        ((org.apache.axis.client.Service) super.service).setTypeMappingVersion("1.1");
-    }
-
-    protected org.apache.axis.client.Call createCall() throws java.rmi.RemoteException {
-        try {
-            org.apache.axis.client.Call _call = super._createCall();
-            if (super.maintainSessionSet) {
-                _call.setMaintainSession(super.maintainSession);
-            }
-            if (super.cachedUsername != null) {
-                _call.setUsername(super.cachedUsername);
-            }
-            if (super.cachedPassword != null) {
-                _call.setPassword(super.cachedPassword);
-            }
-            if (super.cachedEndpoint != null) {
-                _call.setTargetEndpointAddress(super.cachedEndpoint);
-            }
-            if (super.cachedTimeout != null) {
-                _call.setTimeout(super.cachedTimeout);
-            }
-            if (super.cachedPortName != null) {
-                _call.setPortName(super.cachedPortName);
-            }
-            java.util.Enumeration keys = super.cachedProperties.keys();
-            while (keys.hasMoreElements()) {
-                String key = (String) keys.nextElement();
-                _call.setProperty(key, super.cachedProperties.get(key));
-            }
-            return _call;
-        } catch (Throwable _t) {
-            throw new org.apache.axis.AxisFault("Failure trying to get the Call object", _t);
-        }
-    }
-
-    public Integer SMSMessageAccept(String xmlReq, javax.xml.rpc.holders.IntHolder SMSMessageAcceptResult, javax.xml.rpc.holders.StringHolder xmlResp) throws java.rmi.RemoteException {
-        Integer success = null;
-        if (super.cachedEndpoint == null) {
-            throw new org.apache.axis.NoEndPointException();
-        }
-        org.apache.axis.client.Call _call = createCall();
-        _call.setOperation(_operations[0]);
-        _call.setUseSOAPAction(true);
-        _call.setSOAPActionURI("http://tempuri.org/SMSMessageAccept");
-        _call.setEncodingStyle(null);
-        _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
-        _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
-        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
-        _call.setOperationName(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAccept"));
-
-        setRequestHeaders(_call);
-        setAttachments(_call);
-        try {
-            Object _resp = _call.invoke(new Object[]{xmlReq});
-
-            if (_resp instanceof java.rmi.RemoteException) {
-                throw (java.rmi.RemoteException) _resp;
-            } else {
-                extractAttachments(_call);
-                java.util.Map _output;
-                _output = _call.getOutputParams();
-                try {
-                    success = ((Integer) _output.get(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAcceptResult"))).intValue();
-                } catch (Exception _exception) {
-                    success = ((Integer) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://tempuri.org/", "SMSMessageAcceptResult")), int.class)).intValue();
-                }
-                try {
-                    xmlResp.value = (String) _output.get(new javax.xml.namespace.QName("http://tempuri.org/", "xmlResp"));
-                } catch (Exception _exception) {
-                    xmlResp.value = (String) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://tempuri.org/", "xmlResp")), String.class);
-                }
-            }
-        } catch (org.apache.axis.AxisFault axisFaultException) {
-            throw axisFaultException;
-        }
-        return success;
-    }
-
-}
diff --git a/smartor/src/main/java/WebServiceClient/MessagingInsertSoap_PortType.java b/smartor/src/main/java/WebServiceClient/MessagingInsertSoap_PortType.java
deleted file mode 100644
index d1068ed..0000000
--- a/smartor/src/main/java/WebServiceClient/MessagingInsertSoap_PortType.java
+++ /dev/null
@@ -1,12 +0,0 @@
-/**
- * MessagingInsertSoap_PortType.java
- *
- * This file was auto-generated from WSDL
- * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
- */
-
-package WebServiceClient;
-
-public interface MessagingInsertSoap_PortType extends java.rmi.Remote {
-    public Integer SMSMessageAccept(String xmlReq, javax.xml.rpc.holders.IntHolder SMSMessageAcceptResult, javax.xml.rpc.holders.StringHolder xmlResp) throws java.rmi.RemoteException;
-}
diff --git a/smartor/src/main/java/WebServiceClient/MessagingInsertTestCase.java b/smartor/src/main/java/WebServiceClient/MessagingInsertTestCase.java
deleted file mode 100644
index 2576c8c..0000000
--- a/smartor/src/main/java/WebServiceClient/MessagingInsertTestCase.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * MessagingInsertTestCase.java
- * <p>
- * This file was auto-generated from WSDL
- * by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
- */
-
-package WebServiceClient;
-
-public class MessagingInsertTestCase extends junit.framework.TestCase {
-    public MessagingInsertTestCase(String name) {
-        super(name);
-    }
-
-    public void testMessagingInsertSoap12WSDL() throws Exception {
-        javax.xml.rpc.ServiceFactory serviceFactory = javax.xml.rpc.ServiceFactory.newInstance();
-        java.net.URL url = new java.net.URL(new MessagingInsertLocator().getMessagingInsertSoap12Address() + "?WSDL");
-        javax.xml.rpc.Service service = serviceFactory.createService(url, new MessagingInsertLocator().getServiceName());
-        assertTrue(service != null);
-    }
-
-    public void test1MessagingInsertSoap12SMSMessageAccept() throws Exception {
-        MessagingInsertSoap12Stub binding;
-        try {
-            binding = (MessagingInsertSoap12Stub) new MessagingInsertLocator().getMessagingInsertSoap12();
-        } catch (javax.xml.rpc.ServiceException jre) {
-            if (jre.getLinkedCause() != null) jre.getLinkedCause().printStackTrace();
-            throw new junit.framework.AssertionFailedError("JAX-RPC ServiceException caught: " + jre);
-        }
-        assertNotNull("binding is null", binding);
-
-        // Time out after a minute
-        binding.setTimeout(60000);
-
-        // Test operation
-        binding.SMSMessageAccept(new String(), new javax.xml.rpc.holders.IntHolder(), new javax.xml.rpc.holders.StringHolder());
-        // TBD - validate results
-    }
-
-    public void testMessagingInsertSoapWSDL() throws Exception {
-        javax.xml.rpc.ServiceFactory serviceFactory = javax.xml.rpc.ServiceFactory.newInstance();
-        java.net.URL url = new java.net.URL(new MessagingInsertLocator().getMessagingInsertSoapAddress() + "?WSDL");
-        javax.xml.rpc.Service service = serviceFactory.createService(url, new MessagingInsertLocator().getServiceName());
-        assertTrue(service != null);
-    }
-
-    public void test2MessagingInsertSoapSMSMessageAccept() throws Exception {
-        MessagingInsertSoap_BindingStub binding;
-        try {
-            binding = (MessagingInsertSoap_BindingStub) new MessagingInsertLocator().getMessagingInsertSoap();
-        } catch (javax.xml.rpc.ServiceException jre) {
-            if (jre.getLinkedCause() != null) jre.getLinkedCause().printStackTrace();
-            throw new junit.framework.AssertionFailedError("JAX-RPC ServiceException caught: " + jre);
-        }
-        assertNotNull("binding is null", binding);
-
-        // Time out after a minute
-        binding.setTimeout(60000);
-
-        // Test operation
-        binding.SMSMessageAccept(new String(), new javax.xml.rpc.holders.IntHolder(), new javax.xml.rpc.holders.StringHolder());
-        // TBD - validate results
-    }
-
-}
diff --git a/smartor/src/main/java/com/smartor/common/MtSubmitSmUtil.java b/smartor/src/main/java/com/smartor/common/MtSubmitSmUtil.java
deleted file mode 100644
index f628f5e..0000000
--- a/smartor/src/main/java/com/smartor/common/MtSubmitSmUtil.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.smartor.common;
-
-import com.alibaba.fastjson2.JSON;
-import com.smartor.domain.MtSubmitSmResp;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * MT娑堟伅鍙戦�佸伐鍏风被锛圫P鍚戣涓氭眹鑱氬钩鍙版彁浜T娑堟伅锛�
- * 鎺ュ彛鍦板潃锛歨ttp://ip:port/submitsm
- * 缂栫爜锛歎TF-8锛岄壌鏉冪畻娉曪細MD5
- */
-@Slf4j
-@Component
-public class MtSubmitSmUtil {
-    private static final RestTemplate restTemplate = new RestTemplate();
-
-    @Value("${sms_password}")
-    private String password;
-
-    @Value("${sms_accountName}")
-    private String accountName;
-
-    @Value("${sms_url}")
-    private String url;
-
-    @Value("${sms_sourceAddr}")
-    private String sourceAddr;
-
-    @Value("${sms_serviceCode}")
-    private String serviceCode;
-
-    @Value("${sms_appkey}")
-    private String appKey;
-
-    @Value("${sms_flag}")
-    private String smsFlag;
-
-
-    /**
-     * 鍙戦�丮T娑堟伅
-     *
-     * @param destAddr 鐩爣鍙风爜
-     * @param content  鐭俊鍐呭
-     * @return MtSubmitSmResp 鍝嶅簲缁撴灉
-     */
-    public Map<String, Object> submitSm(String destAddr, String content) {
-        try {
-            log.info("鍗楀崕闄勪竴鍙戦�佺煭淇★紝destAddr锛歿}锛宑ontent锛歿}", destAddr, content);
-            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
-            String hashHex = buildHashHex(accountName, password, date);
-
-            Map<String, Object> authMap = new HashMap<>();
-            authMap.put("Algorithm", "MD5");
-            authMap.put("Date", date);
-            authMap.put("HASHHEX", hashHex);
-
-            Map<String, Object> reqMap = new HashMap<>();
-            reqMap.put("accountName", accountName);
-            reqMap.put("Authorization", authMap);
-            reqMap.put("DestAddr", destAddr);
-            reqMap.put("SourceAddr", sourceAddr);
-            reqMap.put("Content", smsFlag + content);
-            reqMap.put("ServiceCode", serviceCode);
-
-            HttpHeaders headers = new HttpHeaders();
-            headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
-            headers.set("Accept-Language", "UTF-8");
-            headers.set("app-key", "ak-BFq4NN0TMf92J7KAioNYGz74");
-
-            HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(reqMap), headers);
-            log.info("MtSubmitSm 璇锋眰鍦板潃锛歿}锛岃姹傚弬鏁帮細{}", url + "/submitsm", JSON.toJSONString(reqMap));
-
-            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
-            log.info("MtSubmitSm 鍝嶅簲缁撴灉锛歿}", response.getBody());
-
-            return JSON.parseObject(response.getBody(), Map.class);
-        } catch (Exception e) {
-            log.error("MtSubmitSm 鍙戦�佸け璐ワ紝url锛歿}锛宒estAddr锛歿}锛宔rror锛歿}", url, destAddr, e.getMessage(), e);
-            Map<String, Object> resp = new HashMap<>();
-            resp.put("code", -1);
-            resp.put("message", "鍙戦�佸紓甯革細" + e.getMessage());
-            return resp;
-        }
-    }
-
-    /**
-     * 璁$畻HASHHEX锛歁D5(Algorithm:甯愬彿鍚�:瀵嗙爜:Date)
-     * 渚嬶細MD5:95555:12345:2016-10-09 16:19:43
-     */
-    private static String buildHashHex(String accountName, String password, String date) throws Exception {
-        String plain = "MD5:" + accountName + ":" + password + ":" + date;
-        MessageDigest md = MessageDigest.getInstance("MD5");
-        byte[] bytes = md.digest(plain.getBytes(StandardCharsets.UTF_8));
-        StringBuilder sb = new StringBuilder();
-        for (byte b : bytes) {
-            sb.append(String.format("%02x", b));
-        }
-        return sb.toString();
-    }
-}
diff --git a/smartor/src/main/java/com/smartor/domain/MtSubmitSmResp.java b/smartor/src/main/java/com/smartor/domain/MtSubmitSmResp.java
deleted file mode 100644
index 9e2a6b5..0000000
--- a/smartor/src/main/java/com/smartor/domain/MtSubmitSmResp.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.smartor.domain;
-
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * MT娑堟伅鍙戦�佸搷搴斿弬鏁�
- */
-@Data
-public class MtSubmitSmResp {
-
-
-    /**
-     * 涓嬪彂鐘舵�侊紝0 鎴愬姛锛屽叾浠栧け璐�
-     */
-    private Integer code;
-
-    /**
-     * 澶辫触鏃剁殑閿欒鎻愮ず
-     */
-    private String message;
-
-    /**
-     * 澶辫触鏃剁殑閿欒鎻愮ず
-     */
-    private String success;
-
-    /**
-     * 鍝嶅簲缁撴灉
-     */
-    private String result;
-
-    /**
-     * 涓嬪彂鐘舵��=0鏃舵湁鏁堬紝涓虹郴缁熶骇鐢熺殑msgid锛屽鍙戠敓浜嗛暱鐭俊鎷嗗垎锛屽垯杩斿洖澶氭潯msgid
-     */
-    private List<String> mtSubmitSm;
-}
diff --git a/smartor/src/main/java/com/smartor/domain/ShiyiSmsRequest.java b/smartor/src/main/java/com/smartor/domain/ShiyiSmsRequest.java
deleted file mode 100644
index 96d90a7..0000000
--- a/smartor/src/main/java/com/smartor/domain/ShiyiSmsRequest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package com.smartor.domain;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-/**
- * 鏉窞甯備竴 HIS 鏈嶅姟骞冲彴 5.2 鐭俊涓氬姟 璇锋眰瀵硅薄 (FASONGDX)
- * 瀵瑰簲 TradeMsg XML 鏍硅妭鐐� FASONGDX_IN
- */
-@Data
-@ApiModel(value = "ShiyiSmsRequest", description = "HIS 鐭俊涓氬姟璇锋眰(FASONGDX)")
-public class ShiyiSmsRequest {
-
-    /** 鎿嶄綔鍛樹唬鐮� */
-    @ApiModelProperty(value = "鎿嶄綔鍛樹唬鐮�")
-    private String caozuoydm;
-
-    /** 鎿嶄綔鍛樺鍚� */
-    @ApiModelProperty(value = "鎿嶄綔鍛樺鍚�")
-    private String caozuoyxm;
-
-    /** 鎿嶄綔鏃ユ湡 yyyy-MM-dd HH:mm:ss */
-    @ApiModelProperty(value = "鎿嶄綔鏃ユ湡 yyyy-MM-dd HH:mm:ss")
-    private String caozuorq;
-
-    /** 绯荤粺鏍囪瘑 */
-    @ApiModelProperty(value = "绯荤粺鏍囪瘑")
-    private String xitongbs;
-
-    /** 鍒嗛櫌浠g爜 */
-    @ApiModelProperty(value = "鍒嗛櫌浠g爜")
-    private String fenyuandm;
-
-    /** 鏈烘瀯浠g爜 */
-    @ApiModelProperty(value = "鏈烘瀯浠g爜")
-    private String jigoudm;
-
-    /** 鏈烘瀯鍚嶇О */
-    @ApiModelProperty(value = "鏈烘瀯鍚嶇О")
-    private String jigoumc;
-
-    /** 鏈烘瀯楠岃瘉鐮� */
-    @ApiModelProperty(value = "鏈烘瀯楠岃瘉鐮�")
-    private String jigouyzm;
-
-    /** 鎺ユ敹鏈烘瀯浠g爜 */
-    @ApiModelProperty(value = "鎺ユ敹鏈烘瀯浠g爜")
-    private String jieshoujgdm;
-
-    /** 缁堢绾у埆 */
-    @ApiModelProperty(value = "缁堢绾у埆")
-    private String zhongduanjb;
-
-    /** 缁堢娴佹按 */
-    @ApiModelProperty(value = "缁堢娴佹按")
-    private String zhongduanls;
-
-    /** IP 鍦板潃 */
-    @ApiModelProperty(value = "IP 鍦板潃")
-    private String ipaddress;
-
-    /** 涓氬姟绫诲瀷 */
-    @ApiModelProperty(value = "涓氬姟绫诲瀷")
-    private String yewulx;
-
-    /** 鎺ュ叆鍦烘墍浠g爜 */
-    @ApiModelProperty(value = "鎺ュ叆鍦烘墍浠g爜")
-    private String jierucsdm;
-
-    /** 鐭俊绫诲瀷 0锛氭櫘閫氱煭淇� */
-    @ApiModelProperty(value = "鐭俊绫诲瀷,榛樿 0 鏅�氱煭淇�", required = true)
-    private String duanxinlx;
-
-    /** 鎵嬫満鍙� */
-    @ApiModelProperty(value = "鎵嬫満鍙�", required = true)
-    private String shoujihao;
-
-    /** 鐭俊鍐呭 */
-    @ApiModelProperty(value = "鐭俊鍐呭", required = true)
-    private String duanxinnr;
-}
\ No newline at end of file
diff --git a/smartor/src/main/java/com/smartor/domain/ShiyiSmsResponse.java b/smartor/src/main/java/com/smartor/domain/ShiyiSmsResponse.java
deleted file mode 100644
index 5c4dcf0..0000000
--- a/smartor/src/main/java/com/smartor/domain/ShiyiSmsResponse.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.smartor.domain;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-/**
- * 鏉窞甯備竴 HIS 鏈嶅姟骞冲彴 5.2 鐭俊涓氬姟 鍝嶅簲瀵硅薄 (FASONGDX_OUT)
- */
-@Data
-@ApiModel(value = "ShiyiSmsResponse", description = "HIS 鐭俊涓氬姟鍝嶅簲(FASONGDX_OUT)")
-public class ShiyiSmsResponse {
-
-    /** 閿欒鍙凤紝0 鎴愬姛锛�1 澶辫触锛�2 HIS 寮傚父锛�99 鍙傛暟寮傚父锛�<0 绯荤粺寮傚父 */
-    @ApiModelProperty(value = "閿欒鍙� 0 鎴愬姛锛涘叾浠栧け璐�")
-    private String errno;
-
-    /** 閿欒鎻忚堪 */
-    @ApiModelProperty(value = "閿欒鎻忚堪")
-    private String errmsg;
-
-    /** 鎵╁睍閿欒鎻忚堪 */
-    @ApiModelProperty(value = "鎵╁睍閿欒鎻忚堪")
-    private String errmsgex;
-
-    /** HIS 渚ф秷鎭� ID */
-    @ApiModelProperty(value = "HIS 渚ф秷鎭� ID")
-    private String messageId;
-
-    /** 鐭俊 ID */
-    @ApiModelProperty(value = "鐭俊 ID")
-    private String duanxinid;
-
-    /** 鍘熷鍝嶅簲 XML锛堣皟璇曠敤锛� */
-    @ApiModelProperty(value = "鍘熷鍝嶅簲 XML")
-    private String rawXml;
-
-    public boolean isSuccess() {
-        return "0".equals(errno);
-    }
-}
diff --git a/smartor/src/main/java/com/smartor/domain/XinHuaWXReq.java b/smartor/src/main/java/com/smartor/domain/XinHuaWXReq.java
deleted file mode 100644
index fab95b7..0000000
--- a/smartor/src/main/java/com/smartor/domain/XinHuaWXReq.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.smartor.domain;
-
-import com.ruoyi.common.annotation.Excel;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-
-/**
- * 鏂板崕鍖婚櫌鍏紬鍙峰叆鍙�
- *
- * @author lihu
- * @date 2024-08-31
- */
-@ApiModel(value = "XinHuaWXReq", description = "鏂板崕鍖婚櫌鍏紬鍙峰叆鍙�")
-@Data
-public class XinHuaWXReq {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 鎺ュ彛鏈嶅姟鍚嶏紝鍥哄畾鍊�
-     */
-    @ApiModelProperty(value = "鎺ュ彛鏈嶅姟鍚嶏紝鍥哄畾鍊�")
-    private String service = "smarthos.pat.notice";
-
-
-    /**
-     * 搴旂敤缂栧彿
-     */
-    @ApiModelProperty(value = "搴旂敤缂栧彿")
-    private String appid;
-
-
-    /**
-     * 鎮h�呯紪鍙�
-     */
-    @ApiModelProperty(value = "鎮h�呯紪鍙�")
-    private String patientid;
-
-    /**
-     * 鎮h�呭鍚�
-     */
-    @ApiModelProperty(value = "鎮h�呭鍚�")
-    private String patientname;
-    /**
-     * 璇佷欢鍙�
-     */
-    @Excel(name = "  璇佷欢鍙�")
-    @ApiModelProperty(value = "璇佷欢鍙�")
-    private String idcard;
-
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    @ApiModelProperty(value = "鎵嬫満鍙风爜")
-    private String mobile;
-
-    /**
-     * 灏辫瘖鍗″彿
-     */
-    @ApiModelProperty(value = "灏辫瘖鍗″彿")
-    private String medcardno;
-
-    /**
-     * 閫氱煡鍐呭
-     */
-    @ApiModelProperty(value = "閫氱煡鍐呭")
-    private String titlename;
-
-    /**
-     * 閾炬帴鍦板潃
-     */
-    @ApiModelProperty(value = "閾炬帴鍦板潃")
-    private String content;
-
-    /**
-     * 璇︽儏鍦板潃
-     */
-    @Excel(name = "閾炬帴鍦板潃")
-    @ApiModelProperty(value = "閾炬帴鍦板潃")
-    private String url;
-
-
-
-
-
-
-}
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java
index 26a970c..6e01e3d 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServicPhoneServiceImpl.java
@@ -9,7 +9,6 @@
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.core.service.IConfigService;
-import com.ruoyi.common.dx.MessageSend;
 import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.*;
 import com.ruoyi.common.utils.http.HttpUtils;
@@ -18,7 +17,6 @@
 import com.ruoyi.system.mapper.SysConfigMapper;
 import com.ruoyi.system.service.ISysConfigService;
 import com.smartor.common.FtpService;
-import com.smartor.common.MtSubmitSmUtil;
 import com.smartor.common.ScheduleSubtaskBuilder;
 import com.smartor.config.PhoneUtils;
 import com.smartor.domain.DTO.ServiceSubtaskDetailDTO;
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
index bcca0f4..7462cd2 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -9,17 +9,20 @@
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.core.service.IConfigService;
-import com.ruoyi.common.dx.MessageSend;
-import com.ruoyi.common.enums.WxGZHEnum;
+import com.ruoyi.message.sms.provider.sltd.ws.MessageSend;
 import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.*;
 import com.ruoyi.common.utils.http.HttpUtils;
 import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
+import com.ruoyi.message.wechat.WechatSendRequest;
+import com.ruoyi.message.wechat.WechatSenderFactory;
 import com.ruoyi.system.domain.SysConfig;
 import com.ruoyi.system.mapper.SysConfigMapper;
 import com.ruoyi.system.service.ISysConfigService;
 import com.smartor.common.FtpService;
-import com.smartor.common.MtSubmitSmUtil;
 import com.smartor.common.ScheduleSubtaskBuilder;
 import com.smartor.config.PhoneUtils;
 import com.smartor.domain.DTO.*;
@@ -165,10 +168,16 @@
     private ISysConfigService configService;
 
     @Autowired
-    private MtSubmitSmUtil mtSubmitSmUtil;
+    private SysConfigMapper sysConfigMapper;
+
+    /**
+     * 娑堟伅鍙戦�佹柟宸ュ巶锛堢煭淇�/寰俊鍏紬鍙凤級锛屾浛浠e師鏉ョ洿鎺ヨ皟鐢ㄥ悇绔欑偣鍙戦�佷唬鐮佺殑鍐欐硶
+     */
+    @Autowired
+    private SmsSenderFactory smsSenderFactory;
 
     @Autowired
-    private SysConfigMapper sysConfigMapper;
+    private WechatSenderFactory wechatSenderFactory;
 
     @Autowired
     private RedisTemplate redisTemplate;
@@ -190,9 +199,6 @@
 
     @Value("${req_path}")
     private String req_path;
-
-    @Value("${xhsmsPath}")
-    private String xhsmsPath;
 
     @Value("${phoneUpEveryHour}")
     private Integer phoneUpEveryHour;
@@ -4213,10 +4219,8 @@
         serviceOutPath.setUpdateTime(new Date());
         serviceOutPath.setUrl(url);
         iServiceOutPathService.updateServiceOutPath(serviceOutPath);
-        Map<String, String> map = new HashMap<>();
-        map.put("phone", serviceSubtask.getPhone());
-        map.put("content", sendMagParam.getContent());
-        HttpUtil.postJsonRequest(xhsmsPath, new Gson().toJson(map));
+        //鐭俊鍙戦�佸凡鏀跺彛鍒� ruoyi-message 妯″潡锛涗笌鍘熷疄鐜颁竴鑷达細涓嶅垽鏂彂閫佺粨鏋�
+        smsSenderFactory.send(active, SmsSendRequest.of(serviceSubtask.getPhone(), sendMagParam.getContent(), serviceSubtask.getOrgid()));
         redisCache.setCacheObject(subTaskId + "recordAccept-hungup", "1", 10, TimeUnit.MINUTES);
         if (StringUtils.isNotEmpty(serviceSubtask.getRemark()))
             serviceSubtask.setRemark("鐢佃瘽鍙戦�佹嫆鎺�,鐭俊琛ュ伩鍙戦�佹垚鍔�");
@@ -5172,9 +5176,11 @@
             sendMagParam.setContent(smsContemt.replace("${wjurl}", sendMagParam.getUrl()));
         }
 
+        //鐭俊鍙戦�侊細鍚勭珯鐐瑰鎺ユ柟寮忓樊寮傝緝澶э紝宸叉敹鍙e埌 ruoyi-message 妯″潡
         if (active.equals("nhfy")) {
-            Map<String, Object> smsResult = mtSubmitSmUtil.submitSm(sendMagParam.getPhone(), sendMagParam.getContent());
-            if (smsResult != null && smsResult.get("result") != null && smsResult.get("result").toString().equals("0")) {
+            SendResult smsResult = smsSenderFactory.send(active,
+                    SmsSendRequest.of(sendMagParam.getPhone(), sendMagParam.getContent(), serviceSubtask.getOrgid()));
+            if (smsResult.isOk()) {
                 resultMap.put("code", "200");
                 resultMap.put("msg", "鍙戦�佹垚鍔�");
                 serviceSubtask.setRemark(StringUtils.isNotEmpty(serviceSubtask.getRemark()) ? serviceSubtask.getRemark() + ";鐭俊鍙戦�佹垚鍔�(鎵嬪姩鎻愪氦)" : "鐭俊鍙戦�佹垚鍔�(鎵嬪姩鎻愪氦)");
@@ -5220,35 +5226,33 @@
             iServiceOutPathService.updateServiceOutPath(serviceOutPath);
 
 
-            //鑾峰彇寰俊鍏紬鍙疯姹備俊鎭牴鎹満鏋処D
-            List<String> wxqqxx = WxGZHEnum.getDescByCode(serviceSubtask.getOrgid());
-            if (CollectionUtils.isEmpty(wxqqxx) || wxqqxx.size() < 4) {
-                resultMap.put("code", -1);
-                resultMap.put("message", "鍙戦�佸紓甯革細" + "銆愬叕浼楀彿銆戣鏈烘瀯鐨勫叕浼楀彿閰嶇疆淇℃伅涓嶅叏锛屾棤娉曢�氳繃鍏紬鍙峰彂閫�");
-                return resultMap;
-            }
-
+            //his鎮h�卛d鏍¢獙锛堜笌鍘熷疄鐜颁竴鑷达細鍏堟牎楠岃繖涓�椤癸級
             if (StringUtils.isEmpty(serviceSubtask.getPatidHis())) {
                 resultMap.put("code", -1);
                 resultMap.put("message", "鍙戦�佸紓甯革細" + "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�,his绯荤粺鐨勬偅鑰卛d涓虹┖");
                 return resultMap;
             }
-            String wxCode = "";
-            wxCode = getWXCode(serviceSubtask.getSfzh(), url, serviceSubtask.getTaskName(), serviceSubtask.getTaskDesc(), patArchive.getTelcode(), serviceSubtask.getSendname(), patArchive.getPatidHis(), wxqqxx);
-            Map map = JSONObject.parseObject(wxCode, Map.class);
-            Boolean wxCodeSuccess = false;
-            if (!map.isEmpty() && map.get("succ") != null) {
-                wxCodeSuccess = (boolean) map.get("succ");
-            }
+
+            //鏈烘瀯閰嶇疆鏍¢獙銆佹姤鏂囩鍚嶄笌杩斿洖鍒ゅ畾鍧囧凡鏀跺彛鍒� ruoyi-message 鐨勫彂閫佹柟瀹炵幇
+            WechatSendRequest wechatRequest = new WechatSendRequest();
+            wechatRequest.setOrgid(serviceSubtask.getOrgid());
+            wechatRequest.setIdCard(serviceSubtask.getSfzh());
+            wechatRequest.setUrl(url);
+            wechatRequest.setTitle(serviceSubtask.getTaskName());
+            wechatRequest.setContent(serviceSubtask.getTaskDesc());
+            wechatRequest.setPhone(patArchive.getTelcode());
+            wechatRequest.setPatientName(serviceSubtask.getSendname());
+            wechatRequest.setPatidHis(patArchive.getPatidHis());
+            SendResult wechatResult = wechatSenderFactory.send(active, wechatRequest);
 
             //鍙戦�佸畬鎴愬悗锛屼慨鏀圭姸鎬�
             serviceSubtask.setSendstate(3L);
-            if (wxCodeSuccess) {
+            if (wechatResult.isOk()) {
                 serviceSubtask.setResult("success");
                 resultMap.put("code", "200");
                 resultMap.put("msg", "鍙戦�佹垚鍔�");
             } else {
-                log.error("銆恠fHandlle銆戝叕浼楀彿鍙戦�佸け璐ワ紝鎮h�呬俊鎭細{}锛岄敊璇俊鎭細{}", serviceSubtask, map.get("msg"));
+                log.error("銆恠fHandlle銆戝叕浼楀彿鍙戦�佸け璐ワ紝鎮h�呬俊鎭細{}锛岄敊璇俊鎭細{}", serviceSubtask, wechatResult.getMessage());
                 resultMap.put("code", -1);
                 resultMap.put("message", "銆愬叕浼楀彿銆戝叕浼楀彿鍙戦�佸け璐�");
                 return resultMap;
@@ -6814,39 +6818,8 @@
         return list;
     }
 
-    private String getWXCode(String idcard, String url, String taskName, String taskDesc, String phone, String setPatientname, String setPatientid, List<String> wxqqxx) {
-        XinHuaWXReq xinHuaWXReq = new XinHuaWXReq();
-        xinHuaWXReq.setIdcard(idcard);
-        xinHuaWXReq.setUrl(url);
-        xinHuaWXReq.setPatientid(setPatientid);
-        xinHuaWXReq.setPatientname(setPatientname);
-        xinHuaWXReq.setMobile(phone);
-        xinHuaWXReq.setMedcardno(null);
-        xinHuaWXReq.setTitlename(taskName);
-        xinHuaWXReq.setContent(taskDesc);
-        xinHuaWXReq.setAppid(wxqqxx.get(1));
-        log.info("銆恎etWXCode銆戝井淇″叕浼楀彿璇锋眰鍙傛暟锛歿}", xinHuaWXReq);
-        String body = new Gson().toJson(xinHuaWXReq);
-        String encode = encode(wxqqxx.get(2).concat(body));
-        Map<String, String> headerMap = new HashMap<>();
-        headerMap.put("sign", encode);
-        String result = HttpUtils.sendPostByHeader(wxqqxx.get(3), body, headerMap);
-        log.info("銆恎etWXCode銆戝井淇″叕浼楀彿杩斿洖鍙傛暟锛歿}", result);
-        JSONObject jsonObject = JSONObject.parseObject(result);
-        String code = (String) jsonObject.toString();
-        return code;
-    }
-    public String encode(String arg) {
-        if (arg == null) {
-            arg = "";
-        }
-        MessageDigest md5 = null;
-        try {
-            md5 = MessageDigest.getInstance("MD5");
-            md5.update(arg.getBytes("UTF-8"));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return toHex(md5.digest());
-    }
+    // ---------------------------------------------------------------------
+    // 璇存槑锛氬師绉佹湁 getWXCode / encode 宸查殢鍙戦�佹柟涓�璧锋敹鍙e埌 ruoyi-message 妯″潡
+    // 锛圶inHuaMpApi锛夛紝姝ゅ宸插垹闄わ紝閬垮厤涓変唤鎷疯礉鍚勫啓涓�濂楃鍚嶉�昏緫銆�
+    // ---------------------------------------------------------------------
 }
diff --git a/smartor/src/main/java/com/smartor/service/impl/SubtaskSmsServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/SubtaskSmsServiceImpl.java
index 2baadda..32dff40 100644
--- a/smartor/src/main/java/com/smartor/service/impl/SubtaskSmsServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/SubtaskSmsServiceImpl.java
@@ -1,7 +1,6 @@
 package com.smartor.service.impl;
 
 import com.ruoyi.common.core.service.ISubtaskSmsService;
-import com.smartor.common.LSHospTokenUtil;
 import com.smartor.domain.ServiceSubtask;
 import com.smartor.mapper.ServiceSubtaskMapper;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -26,6 +25,8 @@
 
     @Override
     public String getLSHospToken(String orgid, String tokenUrl) {
-        return LSHospTokenUtil.getToken(orgid, tokenUrl);
+        //娉細涓芥按鐭俊宸叉敼涓洪�氳繃 LishuiMessageConfigProvider锛堣 com.smartor.message 鍖咃級鍙� token锛�
+        //鏈柟娉曚粎涓哄吋瀹� ruoyi-common 鐨勫巻鍙叉帴鍙d繚鐣�
+        return com.smartor.common.LSHospTokenUtil.getToken(orgid, tokenUrl);
     }
 }
diff --git a/smartor/src/main/java/com/smartor/service/impl/XHGatherPatArchiveServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/XHGatherPatArchiveServiceImpl.java
index f13c364..d434c92 100644
--- a/smartor/src/main/java/com/smartor/service/impl/XHGatherPatArchiveServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/XHGatherPatArchiveServiceImpl.java
@@ -12,6 +12,9 @@
 import com.ruoyi.common.utils.HttpUtil;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.message.SendResult;
+import com.ruoyi.message.sms.SmsSendRequest;
+import com.ruoyi.message.sms.SmsSenderFactory;
 import com.ruoyi.system.domain.SysConfig;
 import com.ruoyi.system.mapper.SysConfigMapper;
 import com.smartor.domain.*;
@@ -57,17 +60,12 @@
     IServiceAppointRecordService iServiceAppointRecordService;
     @Autowired
     private SysConfigMapper sysConfigMapper;
-    @Value("${xhsmsPath}")
-    private String xhsmsPath;
-    // 甯愬彿
-    @Value("${xhsmsAccount}")
-    private String xhsmsAccount;
-    //  鎺ュ彛瀵嗙爜
-    @Value("${xhsmsPwd}")
-    private String xhsmsPwd;
-    // 铏氭嫙鎺ュ叆鐮�
-    @Value("${xhsmsjrm}")
-    private String xhsmsjrm;
+
+    /**
+     * 娑堟伅鍙戦�佹柟宸ュ巶锛堢煭淇�/寰俊鍏紬鍙凤級锛屾浛浠e師鏉ョ洿鎺ユ敞鍏� xhsms* 閰嶇疆 + HttpUtils 鐨勫啓娉�
+     */
+    @Autowired
+    private SmsSenderFactory smsSenderFactory;
 
 
     /**
@@ -135,28 +133,11 @@
                 // 绗簩姝ワ細澶勭悊鍋滆瘖璁板綍淇℃伅
                 for (ServiceAppointRecord serviceAppointRecord : appointRecordFromHIS) {
                     String replace = smsContemt.replace("${patFileName}", StringUtils.defaultString(serviceAppointRecord.getPatFileName())).replace("${registTimeRange}", StringUtils.defaultString(serviceAppointRecord.getRegistTimeRange())).replace("${registDeptName}", StringUtils.defaultString(serviceAppointRecord.getRegistDeptName())).replace("${treatDoctName}", StringUtils.defaultString(serviceAppointRecord.getTreatDoctName()));
-                    Map<String, String> map2 = new HashMap<String, String>();
-                    map2.put("action", "send");
-                    map2.put("account", xhsmsAccount);
-                    map2.put("password", xhsmsPwd);
-                    map2.put("mobile", serviceAppointRecord.getPatTel());
-                    map2.put("content", replace);
-                    map2.put("extno", xhsmsjrm);
-                    map2.put("rt", "json");
-                    StringBuilder encodedParams = new StringBuilder();
-
-                    for (Map.Entry<String, String> entry : map2.entrySet()) {
-                        if (encodedParams.length() > 0) {
-                            encodedParams.append("&");
-                        }
-                        // 瀵归敭鍜屽�艰繘琛孶RL缂栫爜
-                        String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
-                        String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
-                        encodedParams.append(encodedKey).append("=").append(encodedValue);
-                    }
-                    Boolean isSuccess = HttpUtils.sendPost(xhsmsPath, encodedParams.toString());
-                    if (isSuccess) {
-                        log.info("---澶勭悊鍋滆瘖璁板綍淇℃伅鍙戦�佹垚鍔�,鍏ュ弬涓�:{}", encodedParams.toString());
+                    //鐭俊鍙戦�佸凡鏀跺彛鍒� ruoyi-message 妯″潡锛堟柊鍗庨�氶亾璧拌〃鍗曟ā寮忥紝涓庡師瀹炵幇涓�鑷达級
+                    SendResult sendResult = smsSenderFactory.send("xh",
+                            SmsSendRequest.of(serviceAppointRecord.getPatTel(), replace));
+                    if (sendResult.isOk()) {
+                        log.info("---澶勭悊鍋滆瘖璁板綍淇℃伅鍙戦�佹垚鍔�,鍏ュ弬涓�:{}", sendResult.getRawResponse());
                         serviceAppointRecord.setSendTime(new Date());
                         serviceAppointRecord.setSenderName("绯荤粺绠$悊鍛�");
                         iServiceAppointRecordService.insertServiceAppointRecord(serviceAppointRecord);

--
Gitblit v1.9.3