From 900fec8ee44f98483192da893f2c346c0464daa5 Mon Sep 17 00:00:00 2001 From: wanggeng <450292408@qq.com> Date: Sat, 7 Jan 2023 16:01:28 +0800 Subject: [PATCH] fc --- .gitignore | 36 +++++ pom.xml | 145 ++++++++++++++++++ readme.md | 2 + .../smssender/SmsSenderApplication.java | 15 ++ .../config/HuaChuangSmsProperties.java | 62 ++++++++ .../smssender/controller/SmsController.java | 75 +++++++++ .../cn/com/tenlion/smssender/dao/ISmsDao.java | 19 +++ .../smssender/enums/SmsSendStatus.java | 31 ++++ .../smssender/kafka/KafkaConsumer.java | 68 ++++++++ .../pojo/HuaChuangSmsSendResult.java | 108 +++++++++++++ .../tenlion/smssender/pojo/MobileContent.java | 42 +++++ .../smssender/pojo/bos/HuaChuangSmsBO.java | 79 ++++++++++ .../smssender/pojo/vos/BaseSmsSendVO.java | 40 +++++ .../smssender/pojo/vos/SmsP2PSendVO.java | 27 ++++ .../tenlion/smssender/pojo/vos/SmsSendVO.java | 44 ++++++ .../IHuaChuangSmsSendRemoteService.java | 30 ++++ .../smssender/service/BaseSmsSendService.java | 45 ++++++ .../service/IHuaChuangSmsSendService.java | 28 ++++ .../smssender/service/ISmsSendService.java | 28 ++++ .../impl/HuaChuangSmsSendServiceImpl.java | 122 +++++++++++++++ .../service/impl/SmsSendServiceImpl.java | 31 ++++ .../com/tenlion/smssender/util/SmsUtil.java | 28 ++++ src/main/resources/application.yml | 85 ++++++++++ .../resources/mybatis/mapper/sms-mapper.xml | 24 +++ src/main/resources/mybatis/mybatis-config.xml | 15 ++ .../smssender/SmsSenderApplicationTests.java | 13 ++ 26 files changed, 1242 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 readme.md create mode 100644 src/main/java/cn/com/tenlion/smssender/SmsSenderApplication.java create mode 100644 src/main/java/cn/com/tenlion/smssender/config/HuaChuangSmsProperties.java create mode 100644 src/main/java/cn/com/tenlion/smssender/controller/SmsController.java create mode 100644 src/main/java/cn/com/tenlion/smssender/dao/ISmsDao.java create mode 100644 src/main/java/cn/com/tenlion/smssender/enums/SmsSendStatus.java create mode 100644 src/main/java/cn/com/tenlion/smssender/kafka/KafkaConsumer.java create mode 100644 src/main/java/cn/com/tenlion/smssender/pojo/HuaChuangSmsSendResult.java create mode 100644 src/main/java/cn/com/tenlion/smssender/pojo/MobileContent.java create mode 100644 src/main/java/cn/com/tenlion/smssender/pojo/bos/HuaChuangSmsBO.java create mode 100644 src/main/java/cn/com/tenlion/smssender/pojo/vos/BaseSmsSendVO.java create mode 100644 src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsP2PSendVO.java create mode 100644 src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsSendVO.java create mode 100644 src/main/java/cn/com/tenlion/smssender/remote/IHuaChuangSmsSendRemoteService.java create mode 100644 src/main/java/cn/com/tenlion/smssender/service/BaseSmsSendService.java create mode 100644 src/main/java/cn/com/tenlion/smssender/service/IHuaChuangSmsSendService.java create mode 100644 src/main/java/cn/com/tenlion/smssender/service/ISmsSendService.java create mode 100644 src/main/java/cn/com/tenlion/smssender/service/impl/HuaChuangSmsSendServiceImpl.java create mode 100644 src/main/java/cn/com/tenlion/smssender/service/impl/SmsSendServiceImpl.java create mode 100644 src/main/java/cn/com/tenlion/smssender/util/SmsUtil.java create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/mybatis/mapper/sms-mapper.xml create mode 100644 src/main/resources/mybatis/mybatis-config.xml create mode 100644 src/test/java/cn/com/tenlion/smssender/SmsSenderApplicationTests.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..120141f --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +.mvn/* +mvnw* \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..43736b4 --- /dev/null +++ b/pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.6 + + + cn.com.tenlion + sms-sender + 0.0.1-SNAPSHOT + sms-sender + sms-sender + + 1.8 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.springframework.kafka + spring-kafka + + + + mysql + mysql-connector-java + 8.0.30 + runtime + + + + com.github.pagehelper + pagehelper + 5.3.1 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 3.0.0 + + + com.alibaba + druid-spring-boot-starter + 1.2.15 + + + + com.alibaba.fastjson2 + fastjson2 + 2.0.20 + + + + joda-time + joda-time + 2.12.1 + + + + ink.wgink + basic-rpc-rest + 2.0-SNAPSHOT + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + ZIP + + + non-exists + non-exists + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + + target/lib + false + false + runtime + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + **/*.properties + **/*.xml + **/*.yml + static/** + templates/** + mybatis/** + + + + + + + diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..33896e9 --- /dev/null +++ b/readme.md @@ -0,0 +1,2 @@ +alter table m_smessage_short_message +add short_message_uuid char(50) null comment '调用这记录ID' after short_message_uid; \ No newline at end of file diff --git a/src/main/java/cn/com/tenlion/smssender/SmsSenderApplication.java b/src/main/java/cn/com/tenlion/smssender/SmsSenderApplication.java new file mode 100644 index 0000000..d854587 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/SmsSenderApplication.java @@ -0,0 +1,15 @@ +package cn.com.tenlion.smssender; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@MapperScan(basePackages = {"cn.com.tenlion.**.dao"}) +@SpringBootApplication(scanBasePackages={"cn.com.tenlion", "ink.wgink"}) +public class SmsSenderApplication { + + public static void main(String[] args) { + SpringApplication.run(SmsSenderApplication.class, args); + } + +} diff --git a/src/main/java/cn/com/tenlion/smssender/config/HuaChuangSmsProperties.java b/src/main/java/cn/com/tenlion/smssender/config/HuaChuangSmsProperties.java new file mode 100644 index 0000000..9f1a930 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/config/HuaChuangSmsProperties.java @@ -0,0 +1,62 @@ +package cn.com.tenlion.smssender.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @ClassName: HuaChuangSmsConfig + * @Description: + * @Author: wanggeng + * @Date: 2022/12/6 21:38 + * @Version: 1.0 + */ +@Configuration +@ConfigurationProperties(prefix = "sms.hua-chuang") +public class HuaChuangSmsProperties { + + private Boolean active; + private String url; + private String username; + private String password; + private String extno; + + public Boolean getActive() { + return active != null && active; + } + + public void setActive(Boolean active) { + this.active = active; + } + + public String getUrl() { + return url == null ? "" : url.trim(); + } + + public void setUrl(String url) { + this.url = url; + } + + public String getUsername() { + return username == null ? "" : username.trim(); + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password == null ? "" : password.trim(); + } + + public void setPassword(String password) { + this.password = password; + } + + public String getExtno() { + return extno == null ? "" : extno.trim(); + } + + public void setExtno(String extno) { + this.extno = extno; + } +} diff --git a/src/main/java/cn/com/tenlion/smssender/controller/SmsController.java b/src/main/java/cn/com/tenlion/smssender/controller/SmsController.java new file mode 100644 index 0000000..a9e69ea --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/controller/SmsController.java @@ -0,0 +1,75 @@ +package cn.com.tenlion.smssender.controller; + +import cn.com.tenlion.smssender.pojo.bos.HuaChuangSmsBO; +import cn.com.tenlion.smssender.pojo.vos.SmsP2PSendVO; +import cn.com.tenlion.smssender.pojo.vos.SmsSendVO; +import cn.com.tenlion.smssender.service.ISmsSendService; +import com.alibaba.fastjson2.JSON; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.support.SendResult; +import org.springframework.util.concurrent.ListenableFuture; +import org.springframework.util.concurrent.ListenableFutureCallback; +import org.springframework.web.bind.annotation.*; + +import java.util.Arrays; + +/** + * @ClassName: TestController + * @Description: + * @Author: wanggeng + * @Date: 2022/12/6 22:09 + * @Version: 1.0 + */ +@RestController +@RequestMapping("sms") +public class SmsController { + + @Autowired + private ISmsSendService smsSendService; + @Autowired + private KafkaTemplate kafkaTemplate; + + @PostMapping("send") + public void send(@RequestBody SmsSendVO smsSendVO) { + HuaChuangSmsBO huaChuangSmsBO = new HuaChuangSmsBO(); + huaChuangSmsBO.setShortMessageNo(smsSendVO.getShortMessageNo()); + huaChuangSmsBO.setMobiles(smsSendVO.getMobiles()); + huaChuangSmsBO.setContent(smsSendVO.getContent()); + smsSendService.send(huaChuangSmsBO); + } + + @PostMapping("send-p2p") + public void sendP2P(@RequestBody SmsP2PSendVO smsP2PSendVO) { + HuaChuangSmsBO huaChuangSmsBO = new HuaChuangSmsBO(); + huaChuangSmsBO.setShortMessageNo(smsP2PSendVO.getShortMessageNo()); + huaChuangSmsBO.setMobileContents(smsP2PSendVO.getMobileContents()); + smsSendService.sendP2P(huaChuangSmsBO); + } + + @GetMapping("kafka-test/{count}") + public void sendP2P(@PathVariable("count") Integer count) { + SmsSendVO smsSendVO = new SmsSendVO(); + smsSendVO.setShortMessageNo("test-short-message-uuid"); + smsSendVO.setMobiles(Arrays.asList("18634604067", "19147182823")); + smsSendVO.setContent("测试"); + for (int i = 0; i < count; i++) { + ListenableFuture> smsSendListenableFuture = kafkaTemplate.send("sms_send", JSON.toJSONString(smsSendVO)); + smsSendListenableFuture.addCallback(new ListenableFutureCallback>() { + + @Override + public void onFailure(Throwable ex) { + System.out.println("发送失败"); + ex.printStackTrace(); + } + + @Override + public void onSuccess(SendResult result) { + System.out.println("发送成功"); + System.out.println(result.toString()); + } + }); + } + } + +} diff --git a/src/main/java/cn/com/tenlion/smssender/dao/ISmsDao.java b/src/main/java/cn/com/tenlion/smssender/dao/ISmsDao.java new file mode 100644 index 0000000..84d9353 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/dao/ISmsDao.java @@ -0,0 +1,19 @@ +package cn.com.tenlion.smssender.dao; + +import org.springframework.stereotype.Repository; + +import java.util.Map; + +/** + * @ClassName: ISmsDao + * @Description: 短信 + * @Author: wanggeng + * @Date: 2022/12/7 14:54 + * @Version: 1.0 + */ +@Repository +public interface ISmsDao { + + void updateStatus(Map params); + +} diff --git a/src/main/java/cn/com/tenlion/smssender/enums/SmsSendStatus.java b/src/main/java/cn/com/tenlion/smssender/enums/SmsSendStatus.java new file mode 100644 index 0000000..1d9fd9f --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/enums/SmsSendStatus.java @@ -0,0 +1,31 @@ +package cn.com.tenlion.smssender.enums; + +/** + * @ClassName: SmsSendStatus + * @Description: 发送状态 + * @Author: wanggeng + * @Date: 2022/12/7 15:23 + * @Version: 1.0 + */ +public enum SmsSendStatus { + WAIT(0, "待发送"), + SEND(1, "已发送|已接收"), + CONFIRM(2, "确认送达|确认通知厂家"), + ERROR(-1, "送达失败|通知失败"); + + private Integer value; + private String text; + + SmsSendStatus(Integer value, String text) { + this.value = value; + this.text = text; + } + + public Integer getValue() { + return value == null ? 0 : value; + } + + public String getText() { + return text == null ? "" : text.trim(); + } +} diff --git a/src/main/java/cn/com/tenlion/smssender/kafka/KafkaConsumer.java b/src/main/java/cn/com/tenlion/smssender/kafka/KafkaConsumer.java new file mode 100644 index 0000000..baf82b1 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/kafka/KafkaConsumer.java @@ -0,0 +1,68 @@ +package cn.com.tenlion.smssender.kafka; + +import cn.com.tenlion.smssender.pojo.bos.HuaChuangSmsBO; +import cn.com.tenlion.smssender.pojo.vos.SmsP2PSendVO; +import cn.com.tenlion.smssender.pojo.vos.SmsSendVO; +import cn.com.tenlion.smssender.service.ISmsSendService; +import com.alibaba.fastjson2.JSONObject; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.support.Acknowledgment; +import org.springframework.kafka.support.KafkaHeaders; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +/** + * @ClassName: KafkaConsumer + * @Description: 消费者 + * @Author: wanggeng + * @Date: 2022/12/7 09:50 + * @Version: 1.0 + */ +@Component +public class KafkaConsumer { + private static final Logger LOG = LoggerFactory.getLogger(KafkaConsumer.class); + + @Autowired + private ISmsSendService smsSendService; + + @KafkaListener(topics = "sms_send", groupId = "sms") + public void smsSend(ConsumerRecord record, Acknowledgment ack, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + Optional message = Optional.ofNullable(record.value()); + if (message.isPresent()) { + Object msg = message.get(); + LOG.info("消费了: Topic:" + topic + ",Message:" + msg); + SmsSendVO smsSendVO = JSONObject.parseObject(msg.toString(), SmsSendVO.class); + HuaChuangSmsBO huaChuangSmsBO = new HuaChuangSmsBO(); + huaChuangSmsBO.setShortMessageNo(smsSendVO.getShortMessageNo()); + huaChuangSmsBO.setMobiles(smsSendVO.getMobiles()); + huaChuangSmsBO.setContent(smsSendVO.getContent()); + huaChuangSmsBO.setExNo(smsSendVO.getExNo()); + smsSendService.send(huaChuangSmsBO); + ack.acknowledge(); + } + } + + @KafkaListener(topics = "sms_p2p_send", groupId = "sms") + public void smsP2PSend(ConsumerRecord record, Acknowledgment ack, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) { + Optional message = Optional.ofNullable(record.value()); + if (message.isPresent()) { + Object msg = message.get(); + LOG.info("消费了: Topic:" + topic + ",Message:" + msg); + SmsP2PSendVO smsP2PSendVO = JSONObject.parseObject(msg.toString(), SmsP2PSendVO.class); + HuaChuangSmsBO huaChuangSmsBO = new HuaChuangSmsBO(); + huaChuangSmsBO.setShortMessageNo(smsP2PSendVO.getShortMessageNo()); + huaChuangSmsBO.setMobileContents(smsP2PSendVO.getMobileContents()); + huaChuangSmsBO.setExNo(smsP2PSendVO.getExNo()); + smsSendService.sendP2P(huaChuangSmsBO); + ack.acknowledge(); + } + } + + +} diff --git a/src/main/java/cn/com/tenlion/smssender/pojo/HuaChuangSmsSendResult.java b/src/main/java/cn/com/tenlion/smssender/pojo/HuaChuangSmsSendResult.java new file mode 100644 index 0000000..586ca4d --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/pojo/HuaChuangSmsSendResult.java @@ -0,0 +1,108 @@ +package cn.com.tenlion.smssender.pojo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: SmsSendResult + * @Description: 短信发送结果 + * @Author: wanggeng + * @Date: 2022/12/6 21:09 + * @Version: 1.0 + */ +public class HuaChuangSmsSendResult { + + private Integer status; + private Integer balance; + private List list; + private String message; + + public Integer getStatus() { + return status == null ? 0 : status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Integer getBalance() { + return balance == null ? 0 : balance; + } + + public void setBalance(Integer balance) { + this.balance = balance; + } + + public List getList() { + return list == null ? new ArrayList<>() : list; + } + + public void setList(List list) { + this.list = list; + } + + public String getMessage() { + return message == null ? "" : message.trim(); + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"status\":") + .append(status); + sb.append(",\"balance\":") + .append(balance); + sb.append(",\"list\":") + .append(list); + sb.append('}'); + return sb.toString(); + } + + public static class PhoneResult { + private String mid; + private String mobile; + private Integer result; + + public String getMid() { + return mid == null ? "" : mid.trim(); + } + + public void setMid(String mid) { + this.mid = mid; + } + + public String getMobile() { + return mobile == null ? "" : mobile.trim(); + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public Integer getResult() { + return result == null ? 0 : result; + } + + public void setResult(Integer result) { + this.result = result; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"mid\":\"") + .append(mid).append('\"'); + sb.append(",\"mobile\":\"") + .append(mobile).append('\"'); + sb.append(",\"result\":") + .append(result); + sb.append('}'); + return sb.toString(); + } + } + +} diff --git a/src/main/java/cn/com/tenlion/smssender/pojo/MobileContent.java b/src/main/java/cn/com/tenlion/smssender/pojo/MobileContent.java new file mode 100644 index 0000000..aca7435 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/pojo/MobileContent.java @@ -0,0 +1,42 @@ +package cn.com.tenlion.smssender.pojo; + +/** + * @ClassName: MobileContent + * @Description: + * @Author: wanggeng + * @Date: 2022/12/7 16:15 + * @Version: 1.0 + */ +public class MobileContent { + + private String mobile; + private String content; + + public String getMobile() { + return mobile == null ? "" : mobile.trim(); + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public String getContent() { + return content == null ? "" : content.trim(); + } + + public void setContent(String content) { + this.content = content; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"mobile\":\"") + .append(mobile).append('\"'); + sb.append(",\"content\":\"") + .append(content).append('\"'); + sb.append('}'); + return sb.toString(); + } + +} diff --git a/src/main/java/cn/com/tenlion/smssender/pojo/bos/HuaChuangSmsBO.java b/src/main/java/cn/com/tenlion/smssender/pojo/bos/HuaChuangSmsBO.java new file mode 100644 index 0000000..46c2167 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/pojo/bos/HuaChuangSmsBO.java @@ -0,0 +1,79 @@ +package cn.com.tenlion.smssender.pojo.bos; + +import cn.com.tenlion.smssender.pojo.MobileContent; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: HuaChuangSmsBO + * @Description: 华创短信 + * @Author: wanggeng + * @Date: 2022/12/6 21:36 + * @Version: 1.0 + */ +public class HuaChuangSmsBO { + + private String shortMessageNo; + private String exNo; + private List mobiles; + private String content; + private List mobileContents; + + public String getShortMessageNo() { + return shortMessageNo == null ? "" : shortMessageNo.trim(); + } + + public void setShortMessageNo(String shortMessageNo) { + this.shortMessageNo = shortMessageNo; + } + + public String getExNo() { + return exNo == null ? "" : exNo.trim(); + } + + public void setExNo(String exNo) { + this.exNo = exNo; + } + + public List getMobiles() { + return mobiles; + } + + public void setMobiles(List mobiles) { + this.mobiles = mobiles; + } + + public String getContent() { + return content == null ? "" : content.trim(); + } + + public void setContent(String content) { + this.content = content; + } + + public List getMobileContents() { + return mobileContents == null ? new ArrayList<>() : mobileContents; + } + + public void setMobileContents(List mobileContents) { + this.mobileContents = mobileContents; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"shortMessageNo\":\"") + .append(shortMessageNo).append('\"'); + sb.append(",\"exNo\":\"") + .append(exNo).append('\"'); + sb.append(",\"mobiles\":") + .append(mobiles); + sb.append(",\"content\":\"") + .append(content).append('\"'); + sb.append(",\"mobileContents\":") + .append(mobileContents); + sb.append('}'); + return sb.toString(); + } +} diff --git a/src/main/java/cn/com/tenlion/smssender/pojo/vos/BaseSmsSendVO.java b/src/main/java/cn/com/tenlion/smssender/pojo/vos/BaseSmsSendVO.java new file mode 100644 index 0000000..3e47331 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/pojo/vos/BaseSmsSendVO.java @@ -0,0 +1,40 @@ +package cn.com.tenlion.smssender.pojo.vos; + +/** + * @ClassName: SmsSendVO + * @Description: 短信发送 + * @Author: wanggeng + * @Date: 2022/12/7 16:04 + * @Version: 1.0 + */ +public class BaseSmsSendVO { + + private String shortMessageNo; + private String exNo; + public String getShortMessageNo() { + return shortMessageNo == null ? "" : shortMessageNo.trim(); + } + + public void setShortMessageNo(String shortMessageNo) { + this.shortMessageNo = shortMessageNo; + } + + public String getExNo() { + return exNo == null ? "" : exNo.trim(); + } + + public void setExNo(String exNo) { + this.exNo = exNo; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"shortMessageNo\":\"") + .append(shortMessageNo).append('\"'); + sb.append(",\"exNo\":\"") + .append(exNo).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsP2PSendVO.java b/src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsP2PSendVO.java new file mode 100644 index 0000000..9de2048 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsP2PSendVO.java @@ -0,0 +1,27 @@ +package cn.com.tenlion.smssender.pojo.vos; + +import cn.com.tenlion.smssender.pojo.MobileContent; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: SmsSendVO + * @Description: 短信发送 + * @Author: wanggeng + * @Date: 2022/12/7 16:04 + * @Version: 1.0 + */ +public class SmsP2PSendVO extends BaseSmsSendVO { + + private List mobileContents; + + public List getMobileContents() { + return mobileContents == null ? new ArrayList<>() : mobileContents; + } + + public void setMobileContents(List mobileContents) { + this.mobileContents = mobileContents; + } + +} diff --git a/src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsSendVO.java b/src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsSendVO.java new file mode 100644 index 0000000..7f9ff3f --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/pojo/vos/SmsSendVO.java @@ -0,0 +1,44 @@ +package cn.com.tenlion.smssender.pojo.vos; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: SmsSendVO + * @Description: 短信发送 + * @Author: wanggeng + * @Date: 2022/12/7 16:04 + * @Version: 1.0 + */ +public class SmsSendVO extends BaseSmsSendVO { + + private List mobiles; + private String content; + + public List getMobiles() { + return mobiles == null ? new ArrayList<>() : mobiles; + } + + public void setMobiles(List mobiles) { + this.mobiles = mobiles; + } + + public String getContent() { + return content == null ? "" : content.trim(); + } + + public void setContent(String content) { + this.content = content; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("{"); + sb.append("\"mobiles\":") + .append(mobiles); + sb.append(",\"content\":\"") + .append(content).append('\"'); + sb.append('}'); + return sb.toString(); + } +} diff --git a/src/main/java/cn/com/tenlion/smssender/remote/IHuaChuangSmsSendRemoteService.java b/src/main/java/cn/com/tenlion/smssender/remote/IHuaChuangSmsSendRemoteService.java new file mode 100644 index 0000000..1de93d1 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/remote/IHuaChuangSmsSendRemoteService.java @@ -0,0 +1,30 @@ +package cn.com.tenlion.smssender.remote; + +import cn.com.tenlion.smssender.pojo.HuaChuangSmsSendResult; +import ink.wgink.annotation.rpc.rest.RemoteService; +import ink.wgink.annotation.rpc.rest.method.RemotePostMethod; +import ink.wgink.annotation.rpc.rest.params.RemoteFormParams; +import ink.wgink.annotation.rpc.rest.params.RemoteServerParams; + +/** + * @ClassName: IHuaChuangSmsSendRemoteService + * @Description: 华创短信发送接口 + * @Author: wanggeng + * @Date: 2022/12/6 21:08 + * @Version: 1.0 + */ +@RemoteService +public interface IHuaChuangSmsSendRemoteService { + + @RemotePostMethod("sms") + HuaChuangSmsSendResult send(@RemoteServerParams String server, + @RemoteFormParams("action") String action, + @RemoteFormParams("account") String account, + @RemoteFormParams("password") String password, + @RemoteFormParams("mobile") String mobile, + @RemoteFormParams("content") String content, + @RemoteFormParams("mobileContentList") String mobileContents, + @RemoteFormParams("extno") String extno, + @RemoteFormParams("rt") String rt); + +} diff --git a/src/main/java/cn/com/tenlion/smssender/service/BaseSmsSendService.java b/src/main/java/cn/com/tenlion/smssender/service/BaseSmsSendService.java new file mode 100644 index 0000000..17b9497 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/service/BaseSmsSendService.java @@ -0,0 +1,45 @@ +package cn.com.tenlion.smssender.service; + +import cn.com.tenlion.smssender.dao.ISmsDao; +import cn.com.tenlion.smssender.enums.SmsSendStatus; +import cn.com.tenlion.smssender.pojo.HuaChuangSmsSendResult; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ClassName: BaseSmsSendService + * @Description: + * @Author: wanggeng + * @Date: 2022/12/7 15:18 + * @Version: 1.0 + */ +public class BaseSmsSendService { + + /** + * 修改状态 + * + * @param smsDao + * @param shortMessageNo + * @param exNo + * @param sendResult + */ + protected void updateStatus(ISmsDao smsDao, String shortMessageNo, String exNo, HuaChuangSmsSendResult sendResult) { + String shortMessageTime = DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")); + for (HuaChuangSmsSendResult.PhoneResult phoneResult : sendResult.getList()) { + Map params = new HashMap<>(); + params.put("shortMessageUid", phoneResult.getMid()); + params.put("shortMessageStatus", sendResult.getStatus() == 0 ? SmsSendStatus.SEND.getValue() : SmsSendStatus.ERROR.getValue()); + params.put("shortMessageTime", shortMessageTime); + params.put("shortMessageRemark", sendResult.getMessage()); + + params.put("shortMessagePhone", phoneResult.getMobile()); + params.put("shortMessageNo", shortMessageNo); + params.put("shortMessageExno", exNo); + smsDao.updateStatus(params); + } + } + +} diff --git a/src/main/java/cn/com/tenlion/smssender/service/IHuaChuangSmsSendService.java b/src/main/java/cn/com/tenlion/smssender/service/IHuaChuangSmsSendService.java new file mode 100644 index 0000000..b28970f --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/service/IHuaChuangSmsSendService.java @@ -0,0 +1,28 @@ +package cn.com.tenlion.smssender.service; + +import cn.com.tenlion.smssender.pojo.bos.HuaChuangSmsBO; + +/** + * @ClassName: IHuaChuangSmsSendService + * @Description: 华创短信发送 + * @Author: wanggeng + * @Date: 2022/12/6 21:34 + * @Version: 1.0 + */ +public interface IHuaChuangSmsSendService { + + /** + * 发送短信 + * + * @param huaChuangSmsBO + */ + void send(HuaChuangSmsBO huaChuangSmsBO); + + /** + * 点对点发送短信 + * + * @param huaChuangSmsBO + */ + void sendP2P(HuaChuangSmsBO huaChuangSmsBO); + +} diff --git a/src/main/java/cn/com/tenlion/smssender/service/ISmsSendService.java b/src/main/java/cn/com/tenlion/smssender/service/ISmsSendService.java new file mode 100644 index 0000000..b6e5ab1 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/service/ISmsSendService.java @@ -0,0 +1,28 @@ +package cn.com.tenlion.smssender.service; + +import cn.com.tenlion.smssender.pojo.bos.HuaChuangSmsBO; + +/** + * @ClassName: ISmsSendService + * @Description: 短信发送接口 + * @Author: wanggeng + * @Date: 2022/12/7 15:44 + * @Version: 1.0 + */ +public interface ISmsSendService { + + /** + * 发送短信 + * + * @param huaChuangSmsBO + */ + void send(HuaChuangSmsBO huaChuangSmsBO); + + /** + * 短信点对点发送 + * + * @param huaChuangSmsBO + */ + void sendP2P(HuaChuangSmsBO huaChuangSmsBO); + +} diff --git a/src/main/java/cn/com/tenlion/smssender/service/impl/HuaChuangSmsSendServiceImpl.java b/src/main/java/cn/com/tenlion/smssender/service/impl/HuaChuangSmsSendServiceImpl.java new file mode 100644 index 0000000..83d706e --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/service/impl/HuaChuangSmsSendServiceImpl.java @@ -0,0 +1,122 @@ +package cn.com.tenlion.smssender.service.impl; + +import cn.com.tenlion.smssender.config.HuaChuangSmsProperties; +import cn.com.tenlion.smssender.dao.ISmsDao; +import cn.com.tenlion.smssender.pojo.HuaChuangSmsSendResult; +import cn.com.tenlion.smssender.pojo.bos.HuaChuangSmsBO; +import cn.com.tenlion.smssender.remote.IHuaChuangSmsSendRemoteService; +import cn.com.tenlion.smssender.service.BaseSmsSendService; +import cn.com.tenlion.smssender.service.IHuaChuangSmsSendService; +import cn.com.tenlion.smssender.util.SmsUtil; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: HuaChuangSmsSendServiceImpl + * @Description: 华创短信发送 + * @Author: wanggeng + * @Date: 2022/12/6 21:37 + * @Version: 1.0 + */ +@Service +public class HuaChuangSmsSendServiceImpl extends BaseSmsSendService implements IHuaChuangSmsSendService { + + private static final Logger LOG = LoggerFactory.getLogger(HuaChuangSmsSendServiceImpl.class); + @Autowired + private HuaChuangSmsProperties huaChuangSmsProperties; + @Autowired + private IHuaChuangSmsSendRemoteService huaChuangSmsSendRemoteService; + @Autowired + private ISmsDao smsDao; + + @Override + @Transactional(rollbackFor = Exception.class) + public void send(HuaChuangSmsBO huaChuangSmsBO) { + if (StringUtils.isBlank(huaChuangSmsBO.getShortMessageNo())) { + LOG.error("Short message no is empty"); + return; + } + if (huaChuangSmsBO.getMobiles().isEmpty()) { + LOG.error("Mobiles list empty,shortMessageNo:{}", huaChuangSmsBO.getShortMessageNo()); + return; + } + if (huaChuangSmsBO.getContent().isEmpty()) { + LOG.error("Content empty,shortMessageNo:{}", huaChuangSmsBO.getShortMessageNo()); + return; + } + LOG.debug("sms: {}", huaChuangSmsBO); + if (!huaChuangSmsProperties.getActive()) { + LOG.info("HuaChuang sms inactive"); + return; + } + String exNo = huaChuangSmsProperties.getExtno() + huaChuangSmsBO.getExNo(); + // 发送短信 + HuaChuangSmsSendResult sendResult = huaChuangSmsSendRemoteService.send( + huaChuangSmsProperties.getUrl(), + "send", + huaChuangSmsProperties.getUsername(), + huaChuangSmsProperties.getPassword(), + SmsUtil.list2Str(huaChuangSmsBO.getMobiles(), ","), + huaChuangSmsBO.getContent(), + null, + exNo, + "json" + ); + // 更新状态 + LOG.debug("send result: {}", sendResult); + updateStatus(smsDao, huaChuangSmsBO.getShortMessageNo(), exNo, sendResult); + } + + @Override + public void sendP2P(HuaChuangSmsBO huaChuangSmsBO) { + if (StringUtils.isBlank(huaChuangSmsBO.getShortMessageNo())) { + LOG.error("Short message no is empty"); + return; + } + if (huaChuangSmsBO.getMobileContents().isEmpty()) { + LOG.error("Mobile content empty,shortMessageNo:{}", huaChuangSmsBO.getShortMessageNo()); + return; + } + LOG.debug("sms: {}", huaChuangSmsBO); + if (!huaChuangSmsProperties.getActive()) { + LOG.info("HuaChuang sms inactive"); + return; + } + List mobileContents = new ArrayList<>(); + huaChuangSmsBO.getMobileContents().forEach(mobileContent -> { + if (StringUtils.isBlank(mobileContent.getMobile())) { + LOG.info("mobile is null,shortMessageNo: {}", huaChuangSmsBO.getShortMessageNo()); + return; + } + if (StringUtils.isBlank(mobileContent.getContent())) { + LOG.info("content is null,shortMessageNo: {}, mobile: {}", huaChuangSmsBO.getShortMessageNo(), mobileContent.getMobile()); + return; + } + mobileContents.add(mobileContent.getMobile() + "#" + mobileContent.getContent()); + }); + String exNo = huaChuangSmsProperties.getExtno() + huaChuangSmsBO.getExNo(); + // 发送短信 + HuaChuangSmsSendResult sendResult = huaChuangSmsSendRemoteService.send( + huaChuangSmsProperties.getUrl(), + "p2p", + huaChuangSmsProperties.getUsername(), + huaChuangSmsProperties.getPassword(), + null, + null, + SmsUtil.list2Str(mobileContents, "\n"), + exNo, + "json" + ); + // 更新状态 + LOG.debug("send result: {}", sendResult); + updateStatus(smsDao, huaChuangSmsBO.getShortMessageNo(), exNo, sendResult); + } + +} diff --git a/src/main/java/cn/com/tenlion/smssender/service/impl/SmsSendServiceImpl.java b/src/main/java/cn/com/tenlion/smssender/service/impl/SmsSendServiceImpl.java new file mode 100644 index 0000000..cae5e46 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/service/impl/SmsSendServiceImpl.java @@ -0,0 +1,31 @@ +package cn.com.tenlion.smssender.service.impl; + +import cn.com.tenlion.smssender.pojo.bos.HuaChuangSmsBO; +import cn.com.tenlion.smssender.service.IHuaChuangSmsSendService; +import cn.com.tenlion.smssender.service.ISmsSendService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @ClassName: SmsSendServiceImpl + * @Description: 短信发送 + * @Author: wanggeng + * @Date: 2022/12/7 15:44 + * @Version: 1.0 + */ +@Service +public class SmsSendServiceImpl implements ISmsSendService { + + @Autowired + private IHuaChuangSmsSendService huaChuangSmsSendService; + + @Override + public void send(HuaChuangSmsBO huaChuangSmsBO) { + huaChuangSmsSendService.send(huaChuangSmsBO); + } + + @Override + public void sendP2P(HuaChuangSmsBO huaChuangSmsBO) { + huaChuangSmsSendService.sendP2P(huaChuangSmsBO); + } +} diff --git a/src/main/java/cn/com/tenlion/smssender/util/SmsUtil.java b/src/main/java/cn/com/tenlion/smssender/util/SmsUtil.java new file mode 100644 index 0000000..1ff4eb9 --- /dev/null +++ b/src/main/java/cn/com/tenlion/smssender/util/SmsUtil.java @@ -0,0 +1,28 @@ +package cn.com.tenlion.smssender.util; + +import java.util.List; + +/** + * @ClassName: SmsUtil + * @Description: + * @Author: wanggeng + * @Date: 2022/12/6 22:59 + * @Version: 1.0 + */ +public class SmsUtil { + + public static String list2Str(List list, String split) { + if (list == null || list.isEmpty()) { + return null; + } + StringBuilder sb = new StringBuilder(); + list.forEach(s -> { + if (sb.length() > 0) { + sb.append(split); + } + sb.append(s); + }); + return sb.toString(); + } + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..cc294e6 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,85 @@ +server: + port: 7777 + servlet: + context-path: /sms + +spring: + datasource: + druid: + url: jdbc:mysql://121.36.71.250:58082/db_cloud_smessage?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false&useSSL=false&serverTimezone=UTC&nullCatalogMeansCurrent=true + db-type: mysql + driver-class-name: com.mysql.cj.jdbc.Driver + username: root + password: admin + initial-size: 2 + min-idle: 2 + max-active: 5 + max-wait: 60000 + time-between-eviction-runs-millis: 60000 + min-evictable-idle-time-millis: 300000 + validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + pool-prepared-statements: true + max-pool-prepared-statement-per-connection-size: 10 + filter: + commons-log: + connection-logger-name: stat,wall,log4j + stat: + log-slow-sql: true + slow-sql-millis: 2000 + connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 + use-global-data-source-stat: true + kafka: + bootstrap-servers: 121.36.71.250:58030 + producer: + # 发生错误后,消息重发的次数。 + retries: 0 + #当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。 + batch-size: 16384 + # 设置生产者内存缓冲区的大小。 + buffer-memory: 33554432 + # 键的序列化方式 + key-serializer: org.apache.kafka.common.serialization.StringSerializer + # 值的序列化方式 + value-serializer: org.apache.kafka.common.serialization.StringSerializer + # acks=0 : 生产者在成功写入消息之前不会等待任何来自服务器的响应。 + # acks=1 : 只要集群的首领节点收到消息,生产者就会收到一个来自服务器成功响应。 + # acks=all :只有当所有参与复制的节点全部收到消息时,生产者才会收到一个来自服务器的成功响应。 + acks: 1 + consumer: + # 自动提交的时间间隔 在spring boot 2.X 版本中这里采用的是值的类型为Duration 需要符合特定的格式,如1S,1M,2H,5D + auto-commit-interval: 1S + # 该属性指定了消费者在读取一个没有偏移量的分区或者偏移量无效的情况下该作何处理: + # latest(默认值)在偏移量无效的情况下,消费者将从最新的记录开始读取数据(在消费者启动之后生成的记录) + # earliest :在偏移量无效的情况下,消费者将从起始位置读取分区的记录 + auto-offset-reset: earliest + # 是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量 + enable-auto-commit: false + # 键的反序列化方式 + key-deserializer: org.apache.kafka.common.serialization.StringDeserializer + # 值的反序列化方式 + value-deserializer: org.apache.kafka.common.serialization.StringDeserializer + listener: + # 在侦听器容器中运行的线程数。 + concurrency: 5 + #listner负责ack,每调用一次,就立即commit + ack-mode: manual_immediate + missing-topics-fatal: false + +mybatis: + config-location: classpath:mybatis/mybatis-config.xml + mapper-locations: classpath*:mybatis/mapper/**/*.xml + +sms: + hua-chuang: + active: true + url: https://124.239.153.233:8014 + username: 922402 + password: WT@6usGwKiantk + extno: 10690402 + +logging: + level: + ink.wgink: debug \ No newline at end of file diff --git a/src/main/resources/mybatis/mapper/sms-mapper.xml b/src/main/resources/mybatis/mapper/sms-mapper.xml new file mode 100644 index 0000000..b86a2d3 --- /dev/null +++ b/src/main/resources/mybatis/mapper/sms-mapper.xml @@ -0,0 +1,24 @@ + + + + + + + UPDATE + m_smessage_short_message + SET + short_message_uid = #{shortMessageUid}, + short_message_status = #{shortMessageStatus}, + short_message_remark = #{shortMessageRemark}, + short_message_time = #{shortMessageTime}, + short_message_exno = #{shortMessageExno}, + short_message_send_count = short_message_send_count + 1 + WHERE + is_delete = 0 + AND + short_message_phone = #{shortMessagePhone} + AND + short_message_no = #{shortMessageNo} + + + \ No newline at end of file diff --git a/src/main/resources/mybatis/mybatis-config.xml b/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..a404e65 --- /dev/null +++ b/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/cn/com/tenlion/smssender/SmsSenderApplicationTests.java b/src/test/java/cn/com/tenlion/smssender/SmsSenderApplicationTests.java new file mode 100644 index 0000000..d5e3573 --- /dev/null +++ b/src/test/java/cn/com/tenlion/smssender/SmsSenderApplicationTests.java @@ -0,0 +1,13 @@ +package cn.com.tenlion.smssender; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SmsSenderApplicationTests { + + @Test + void contextLoads() { + } + +}