diff --git a/JSD-8114配置使用文档.docx b/JSD-8114配置使用文档.docx
new file mode 100644
index 0000000..a554fc5
Binary files /dev/null and b/JSD-8114配置使用文档.docx differ
diff --git a/README.md b/README.md
index aa4a48f..6659b76 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-8144
-JSD-8144 开源任务材料
\ No newline at end of file
+JSD-8144 开源任务材料\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/conf.properties b/conf.properties
new file mode 100644
index 0000000..e043bbc
--- /dev/null
+++ b/conf.properties
@@ -0,0 +1,6 @@
+ecName=xxxx
+apId=xxx
+secretKey=xxxx
+sign=xxxxx
+addSerial=
+url=http://xxxx/sms/norsubmit
\ No newline at end of file
diff --git a/jsd-8144需求文档V1.docx b/jsd-8144需求文档V1.docx
new file mode 100644
index 0000000..232f587
Binary files /dev/null and b/jsd-8144需求文档V1.docx differ
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..c8e6f7c
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,17 @@
+
+
+ com.fr.plugin.nnsz.sms
+
+ yes
+ 1.3
+ 10.0
+ 2018-07-31
+ fr.open
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/SmsService.java b/src/main/java/com/fr/plugin/nnsz/sms/SmsService.java
new file mode 100644
index 0000000..2837942
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/SmsService.java
@@ -0,0 +1,114 @@
+package com.fr.plugin.nnsz.sms;
+
+import com.fr.general.PropertiesUtils;
+import com.fr.json.JSONArray;
+import com.fr.json.JSONObject;
+import com.fr.log.FineLoggerFactory;
+import com.fr.plugin.nnsz.sms.action.SmsAction;
+import com.fr.plugin.nnsz.sms.client.SMSClient;
+import com.fr.plugin.nnsz.sms.entity.SmsRecord;
+import com.fr.plugin.transform.FunctionRecorder;
+import com.fr.stable.fun.impl.AbstractSMSServiceProvider;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author fr.open
+ * @Date 2020/11/3
+ * @Description
+ **/
+@FunctionRecorder
+public class SmsService extends AbstractSMSServiceProvider {
+
+ private SMSClient smsClient;
+
+ private String url;
+
+ public SmsService() {
+ String ecName = PropertiesUtils.getProperties("conf").getProperty("ecName");
+ FineLoggerFactory.getLogger().info("ecName config is {}", ecName);
+ String apid = PropertiesUtils.getProperties("conf").getProperty("apId");
+ FineLoggerFactory.getLogger().info("apId config is {}", apid);
+ String secretKey = PropertiesUtils.getProperties("conf").getProperty("secretKey");
+ FineLoggerFactory.getLogger().info("secretKey config is {}", secretKey);
+ String sign = PropertiesUtils.getProperties("conf").getProperty("sign");
+ FineLoggerFactory.getLogger().info("sign config is {}", sign);
+ String addSerial = PropertiesUtils.getProperties("conf").getProperty("addSerial");
+ FineLoggerFactory.getLogger().info("addSerial config is {}", addSerial);
+ url = PropertiesUtils.getProperties("conf").getProperty("url");
+ FineLoggerFactory.getLogger().info("url config is {}", url);
+ smsClient = new SMSClient(apid, secretKey, ecName, sign, addSerial, url);
+ }
+
+ @Override
+ public Map mapping() {
+ Map map = new HashMap<>();
+ map.put("10", "【xxxx中心】尊敬的管理员,#taskname#于#time#运行失败,请知晓。");
+ map.put("11", "【xxxx中心】尊敬的#name#,您有一个工单号为:#order_number#的待处理工单,请您及时处理!");
+ map.put("13", "【xxxx中心】您好,#webname#系统内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。");
+ map.put("14", "【xxxx中心】尊敬的管理员,#taskname#于#time#运行失败,请知晓。");
+ map.put("15", "【xxxx中心】您好,#taskname#于#time#运行成功。");
+ map.put("16", "【xxxx中心】您的手机验证码为#Verifiecode#,请于10分钟内正确输入。");
+ map.put("17", "【xxxx中心】您好,#webname#系统内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。");
+ map.put("18", "【xxxx中心】恭喜!您的短信服务已经配置成功。");
+ map.put("19", "【xxxx中心】您好,#taskname#于#time#运行成功。");
+ map.put("20", "【xxxx中心】您的手机验证码为#verifiecode#,请于10分钟内正确输入。");
+ map.put("49", "【xxxx中心】您好,#webname#系统日志文件已大于#logsize#M,请及时登录平台进行日志清理。");
+ map.put("50", "【xxxx中心】您好,#webname#系统#clustername#内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。");
+ map.put("51", "【xxxx中心】你好,#task#出错,请及时处理。该任务开始执行时间:#time#");
+ map.put("53", "【xxxx中心】上报任务 #task#,已经到您这里#time#,请尽快处理!");
+ map.put("63", "【xxxx中心】系统检测到,节点#node_id#的系统时间与其他节点不一致。请配置时间服务器,实现节点时间的自动同步。");
+ map.put("64", "【xxxx中心】节点#node_id#,非正常脱离集群环境。请重启该节点,加入集群。");
+ map.put("89", "【xxxx中心】节点#nodename#,与节点#node1name#的jar包不一致,将影响集群工程的稳定性,请前往集群节点管理页面查看详细异常信息,并及时处理。");
+ map.put("90", "【xxxx中心】节点#nodename#情况异常,用户不能正常访问,请及时检查该节点状态。");
+ map.put("125", "【xxxx中心】您有个#proname#任务即将过期,请您尽快办理。");
+ map.put("127", "【xxxx中心】您有个#proname#任务需要处理,请您尽快办理。发起人:#startpeople#,发起时间:#starttime#。");
+ map.put("134", "【xxxx中心】Redis集群#ip_port#节点已无法正常使用,可能原因为:节点宕机、内存已满、其他异常。为避免影响用户使用,请前往状态服务器配置页面查看详情,并及时处理。");
+ map.put("135", "【xxxx中心】文件服务器出现无法读写的情况,可能原因为:文件服务器宕机、磁盘已满、其他异常。为避免影响用户使用,请及时检查文件服务器状态。");
+ map.put("136", "【xxxx中心】您好,#webname#系统#clustername#当前负载状态过高,可能存在宕机风险,请及时关注。建议使用管理系统-智能运维-云端运维功能分析当前系统存在的性能问题。");
+ map.put("239", "【xxxx中心】您好,预警任务#warningname#达到阈值被触发,请及时关注!模板路径:#templatePath#。");
+ map.put("264", "【xxxx中心】更新任务「#job_name#」结束。任务开始于#year#年#month#月#day#日#hr_min#,累计耗时#c_hr#时#c_min#分#c_sec#秒,完成任务:基础表更新 #success_basetable#/#total_basetable# ,自助数据集更新 #success_dataset#/#total_dataset# , 关联更新 #success_relation#/#total_relation#。");
+ map.put("265", "【xxxx中心】报表系统已宕机,请访问运维工具关注问题处理状态或及时进行系统重启。");
+ map.put("269", "【xxxx中心】检查到系统环境配置存有不合理项,请及时查看并改正不合理项。");
+ map.put("266", "【xxxx中心】报表系统已宕机,自动重启系统失败,请及时进行手动重启。");
+ map.put("276", "【xxxx中心】你好,[#taskname#]备份失败,请及时处理,备份时间:#time#。");
+ map.put("367", "【xxxx中心】集群节点#node_name#与基准节点存在不一致文件,且无法自动同步。请检查该节点状态。");
+ map.put("368", "【xxxx中心】集群节点#node_name#与基准节点存在不一致文件,已自动同步与基准节点一致,不一致文件备份在该节点工程WEB-INF/#directory#/下。");
+ map.put("998", "【xxxx中心】节点#nodename1#与节点#nodename2#之间通信异常,无法加入节点管理,请检查集群节点间通信端口是否已开放[TCP:7800,7810, 7820,7830, 7840, 7850,7860,7870][UDP:45588~65536 随机端口]。");
+ map.put("999", "【xxxx中心】节点#node_name#的#type#模块存在异常,暂无法正常提供服务,请及时对异常状况进行排查");
+ return map;
+ }
+
+ @Override
+ public Response sendTest(String s) {
+ return null;
+ }
+
+ @Override
+ public Response send(String template, String mobile, JSONObject jsonObject, String receiver) throws Exception {
+ Iterator it = jsonObject.keys();
+ while (it.hasNext()) {
+ String key = it.next();
+ template = template.replace(key, jsonObject.getString(key));
+ }
+ String res = smsClient.sendMsg(mobile, template);
+ SmsRecord record = new SmsRecord();
+ record.setUrl(url);
+ record.setContent(template);
+ record.setMobile(mobile);
+ record.setResult(res);
+ SyncDBAccessProvider.getDbAccessor().runDMLAction(new SmsAction(record));
+ return Response.create(Response.RES_STATUS_SUCCESS, "发送普通短信成功", JSONObject.create());
+ }
+
+ @Override
+ public Response batchSendSMS(String template, List mobiles, JSONArray params, List receivers) throws Exception {
+ for (int i = 0; i < params.size(); i++) {
+ send(template, receivers.get(i), params.getJSONObject(i), receivers.get(i));
+ }
+ return Response.create(Response.RES_STATUS_SUCCESS, "发送批量短信成功", JSONObject.create());
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/SyncDBAccessProvider.java b/src/main/java/com/fr/plugin/nnsz/sms/SyncDBAccessProvider.java
new file mode 100644
index 0000000..dadb681
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/SyncDBAccessProvider.java
@@ -0,0 +1,42 @@
+package com.fr.plugin.nnsz.sms;
+
+import com.fr.db.fun.impl.AbstractDBAccessProvider;
+import com.fr.plugin.nnsz.sms.dao.SmsRecordDao;
+import com.fr.plugin.nnsz.sms.entity.SmsRecord;
+import com.fr.stable.db.accessor.DBAccessor;
+import com.fr.stable.db.dao.BaseDAO;
+import com.fr.stable.db.dao.DAOProvider;
+
+/**
+ * @Author fr.open
+ * @Date 2020/5/24
+ **/
+public class SyncDBAccessProvider extends AbstractDBAccessProvider {
+
+ private static DBAccessor dbAccessor = null;
+
+ public static DBAccessor getDbAccessor() {
+ return dbAccessor;
+ }
+
+ @Override
+ public DAOProvider[] registerDAO() {
+ return new DAOProvider[]{
+ new DAOProvider() {
+ @Override
+ public Class getEntityClass() {
+ return SmsRecord.class;
+ }
+ @Override
+ public Class extends BaseDAO> getDAOClass() {
+ return SmsRecordDao.class;
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onDBAvailable(DBAccessor dbAccessor) {
+ SyncDBAccessProvider.dbAccessor = dbAccessor;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/action/SmsAction.java b/src/main/java/com/fr/plugin/nnsz/sms/action/SmsAction.java
new file mode 100644
index 0000000..ad530be
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/action/SmsAction.java
@@ -0,0 +1,26 @@
+package com.fr.plugin.nnsz.sms.action;
+
+import com.fr.plugin.nnsz.sms.dao.SmsRecordDao;
+import com.fr.plugin.nnsz.sms.entity.SmsRecord;
+import com.fr.stable.db.action.DBAction;
+import com.fr.stable.db.dao.DAOContext;
+
+/**
+ * @Author fr.open
+ * @Date 2021/7/9
+ * @Description
+ **/
+public class SmsAction implements DBAction {
+
+ private SmsRecord record;
+
+ public SmsAction(SmsRecord record) {
+ this.record = record;
+ }
+
+ @Override
+ public SmsRecord run(DAOContext daoContext) throws Exception {
+ daoContext.getDAO(SmsRecordDao.class).addOrUpdate(record);
+ return record;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/client/JSONUtils.java b/src/main/java/com/fr/plugin/nnsz/sms/client/JSONUtils.java
new file mode 100644
index 0000000..71b3814
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/client/JSONUtils.java
@@ -0,0 +1,102 @@
+package com.fr.plugin.nnsz.sms.client;
+
+import com.fr.third.fasterxml.jackson.core.JsonParseException;
+import com.fr.third.fasterxml.jackson.core.JsonProcessingException;
+import com.fr.third.fasterxml.jackson.databind.JsonMappingException;
+import com.fr.third.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ * @author jhy
+ * @description json工具
+ */
+public class JSONUtils {
+ private final static ObjectMapper objectMapper = new ObjectMapper();
+ private static Logger log = LoggerFactory.getLogger(JSONUtils.class);
+
+ private JSONUtils() {
+
+ }
+
+ public static ObjectMapper getInstance() {
+
+ return objectMapper;
+ }
+
+ /**
+ * javaBean,list,array convert to json string
+ */
+ public static String obj2json(Object obj) {
+
+ try {
+ return objectMapper.writeValueAsString(obj);
+ } catch (JsonProcessingException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * javaBean,list,array convert to json string
+ */
+ public static String obj2jsonInoreString(Object obj) {
+
+ try {
+ return objectMapper.writeValueAsString(obj);
+ } catch (JsonProcessingException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ }
+ return null;
+ }
+ /**
+ * json string convert to javaBean
+ */
+ public static T json2pojo(String jsonStr, Class clazz) {
+ try {
+ return objectMapper.readValue(jsonStr, clazz);
+ } catch (JsonParseException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ } catch (JsonMappingException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * json string convert to map
+ */
+ public static Map json2map(String jsonStr) {
+ try {
+ return objectMapper.readValue(jsonStr, Map.class);
+ } catch (JsonParseException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ } catch (JsonMappingException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ log.error(e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * map convert to javaBean
+ */
+ public static T map2pojo(Map map, Class clazz) {
+ return objectMapper.convertValue(map, clazz);
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/client/Md5Util.java b/src/main/java/com/fr/plugin/nnsz/sms/client/Md5Util.java
new file mode 100644
index 0000000..7e38293
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/client/Md5Util.java
@@ -0,0 +1,112 @@
+package com.fr.plugin.nnsz.sms.client;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.MessageDigest;
+
+/**
+ * @Author fr.open
+ * @Date 2021/7/23
+ * @Description
+ **/
+public class Md5Util {
+ static final char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ /**
+ * 生成MD5码
+ *
+ * @param plainText
+ * 要加密的字符串
+ * @return md5值
+ */
+ public final static String MD5(String plainText) {
+ try {
+ byte[] strTemp = plainText.getBytes("UTF-8");
+ MessageDigest mdTemp = MessageDigest.getInstance("MD5");
+ mdTemp.update(strTemp);
+ byte[] md = mdTemp.digest();
+ int j = md.length;
+ char str[] = new char[j * 2];
+ int k = 0;
+ for (int i = 0; i < j; i++) {
+ byte byte0 = md[i];
+ str[k++] = hexDigits[byte0 >>> 4 & 0xf];
+ str[k++] = hexDigits[byte0 & 0xf];
+ }
+ return new String(str);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 生成MD5码
+ *
+ * @param plainText
+ * 要加密的字符串
+ * @return md5值
+ */
+ public final static String MD5(byte[] plainText) {
+ try {
+ byte[] strTemp = plainText;
+ MessageDigest mdTemp = MessageDigest.getInstance("MD5");
+ mdTemp.update(strTemp);
+ byte[] md = mdTemp.digest();
+ int j = md.length;
+ char str[] = new char[j * 2];
+ int k = 0;
+ for (int i = 0; i < j; i++) {
+ byte byte0 = md[i];
+ str[k++] = hexDigits[byte0 >>> 4 & 0xf];
+ str[k++] = hexDigits[byte0 & 0xf];
+ }
+ return new String(str);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 先进行HmacSHA1转码再进行Base64编码
+ * @param data 要SHA1的串
+ * @param key 秘钥
+ * @return
+ * @throws Exception
+ */
+ public static String HmacSHA1ToBase64(String data, String key) throws Exception {
+ SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
+ Mac mac = Mac.getInstance("HmacSHA1");
+ mac.init(signingKey);
+ byte[] rawHmac = mac.doFinal(data.getBytes());
+ return Base64.encodeBase64String(rawHmac);
+ }
+
+ /**
+ * 校验MD5码
+ *
+ * @param text
+ * 要校验的字符串
+ * @param md5
+ * md5值
+ * @return 校验结果
+ */
+ public static boolean valid(String text, String md5) {
+ return md5.equals(MD5(text)) || md5.equals(MD5(text).toUpperCase());
+ }
+
+ /**
+ *
+ * @param params
+ * @return
+ */
+ public static String MD5(String... params) {
+ StringBuilder sb = new StringBuilder();
+ for (String param : params) {
+ sb.append(param);
+ }
+ return MD5(sb.toString());
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/client/SMSClient.java b/src/main/java/com/fr/plugin/nnsz/sms/client/SMSClient.java
new file mode 100644
index 0000000..d66c701
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/client/SMSClient.java
@@ -0,0 +1,140 @@
+package com.fr.plugin.nnsz.sms.client;
+
+/**
+ * @Author fr.open
+ * @Date 2021/7/23
+ * @Description
+ **/
+
+import com.fr.log.FineLoggerFactory;
+import com.fr.third.org.apache.commons.codec.binary.Base64;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
+
+public class SMSClient {
+
+ private String apId = "xxx";
+ private String secretKey = "xxxx";
+ private String ecName = "xxxx";//集团名称
+ private String sign = "xxxx";//网关签名编码
+ private String addSerial = "";//拓展码 填空
+ public String msg = "这是发送短信的内容!";
+ public String url = "http://xxxx/sms/norsubmit";//请求url
+
+ public SMSClient() {
+ }
+
+ public SMSClient(String apId, String secretKey, String ecName, String sign, String addSerial, String url) {
+ this.apId = apId;
+ this.secretKey = secretKey;
+ this.ecName = ecName;
+ this.sign = sign;
+ this.addSerial = addSerial;
+ this.url =url;
+ }
+
+ public String sendMsg(String mobiles, String content) {
+ SendReq sendReq = new SendReq();
+ sendReq.setApId(apId);
+ sendReq.setEcName(ecName);
+ sendReq.setSecretKey(secretKey);
+ sendReq.setContent(content);
+ sendReq.setMobiles(mobiles);
+ sendReq.setAddSerial(addSerial);
+ sendReq.setSign(sign);
+
+ StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer.append(sendReq.getEcName());
+ stringBuffer.append(sendReq.getApId());
+ stringBuffer.append(sendReq.getSecretKey());
+ stringBuffer.append(sendReq.getMobiles());
+ stringBuffer.append(sendReq.getContent());
+ stringBuffer.append(sendReq.getSign());
+ stringBuffer.append(sendReq.getAddSerial());
+
+ //FineLoggerFactory.getLogger().info(stringBuffer.toString());
+ sendReq.setMac(Md5Util.MD5(stringBuffer.toString()).toLowerCase());
+ //FineLoggerFactory.getLogger().info(sendReq.getMac());
+
+ String reqText = JSONUtils.obj2json(sendReq);
+ String encode = null;
+ try {
+ encode = Base64.encodeBase64String(reqText.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ //FineLoggerFactory.getLogger().info(encode);
+
+ String resStr = sendPost(url, encode);
+
+ FineLoggerFactory.getLogger().info("send mess res is {}",resStr);
+
+ SendRes sendRes = JSONUtils.json2pojo(resStr, SendRes.class);
+
+ if (sendRes.isSuccess() && !"".equals(sendRes.getMsgGroup()) && "success".equals(sendRes.getRspcod())) {
+ } else {
+ }
+ return resStr;
+ }
+
+ /**
+ * main方法测试发送短信,返回1表示成功,0表示失败
+ */
+ /*public static void main(String[] args){
+ int result = sendMsg("xxxxxx",msg);
+ System.out.println(result);
+ }*/
+
+ /**
+ * 向指定 URL 发送POST方法的请求
+ *
+ * @param url 发送请求的 URL
+ * @param param 请求参数
+ * @return 所代表远程资源的响应结果
+ */
+ private static String sendPost(String url, String param) {
+ OutputStreamWriter out = null;
+
+ BufferedReader in = null;
+ String result = "";
+ try {
+ URL realUrl = new URL(url);
+ URLConnection conn = realUrl.openConnection();
+ conn.setRequestProperty("accept", "*/*");
+ conn.setRequestProperty("contentType", "utf-8");
+ conn.setRequestProperty("connection", "Keep-Alive");
+ conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+
+ out = new OutputStreamWriter(conn.getOutputStream());
+ out.write(param);
+ out.flush();
+
+
+ in = new BufferedReader(
+ new InputStreamReader(conn.getInputStream()));
+ String line;
+ while ((line = in.readLine()) != null) {
+ result += "\n" + line;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (out != null) {
+ out.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return result;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/client/SendReq.java b/src/main/java/com/fr/plugin/nnsz/sms/client/SendReq.java
new file mode 100644
index 0000000..a63925d
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/client/SendReq.java
@@ -0,0 +1,81 @@
+package com.fr.plugin.nnsz.sms.client;
+
+/**
+ * @Author fr.open
+ * @Date 2021/7/23
+ * @Description
+ **/
+public class SendReq {
+ private String ecName;//集团客户名称
+ private String apId;//用户名
+ private String secretKey;//密码
+ private String mobiles;//手机号码逗号分隔。(如“xxxx,xxxxx”)
+ private String content;//发送短信内容
+ private String sign;//网关签名编码,必填,签名编码在中国移动集团开通帐号后分配,可以在xxx网页端管理子系统-SMS接口管理功能中下载。
+ private String addSerial;//扩展码,根据向移动公司申请的通道填写,如果申请的精确匹配通道,则填写空字符串(""),否则添加移动公司允许的扩展码。
+ private String mac;//API输入参数签名结果,签名算法:将ecName,apId,secretKey,mobiles,content ,sign,addSerial按照顺序拼接,然后通过md5(32位小写)计算后得出的值。
+
+ public String getEcName() {
+ return ecName;
+ }
+
+ public void setEcName(String ecName) {
+ this.ecName = ecName;
+ }
+
+ public String getApId() {
+ return apId;
+ }
+
+ public void setApId(String apId) {
+ this.apId = apId;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ }
+
+ public String getMobiles() {
+ return mobiles;
+ }
+
+ public void setMobiles(String mobiles) {
+ this.mobiles = mobiles;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getSign() {
+ return sign;
+ }
+
+ public void setSign(String sign) {
+ this.sign = sign;
+ }
+
+ public String getAddSerial() {
+ return addSerial;
+ }
+
+ public void setAddSerial(String addSerial) {
+ this.addSerial = addSerial;
+ }
+
+ public String getMac() {
+ return mac;
+ }
+
+ public void setMac(String mac) {
+ this.mac = mac;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/client/SendRes.java b/src/main/java/com/fr/plugin/nnsz/sms/client/SendRes.java
new file mode 100644
index 0000000..a29ef68
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/client/SendRes.java
@@ -0,0 +1,36 @@
+package com.fr.plugin.nnsz.sms.client;
+
+/**
+ * @Author fr.open
+ * @Date 2021/7/23
+ * @Description
+ **/
+public class SendRes {
+ private String rspcod;//响应码
+ private String msgGroup;//消息批次号,由xxxx平台生成,用于验证短信提交报告和状态报告的一致性(取值msgGroup)注:如果数据验证不通过msgGroup为空
+ private boolean success;
+
+ public String getRspcod() {
+ return rspcod;
+ }
+
+ public void setRspcod(String rspcod) {
+ this.rspcod = rspcod;
+ }
+
+ public String getMsgGroup() {
+ return msgGroup;
+ }
+
+ public void setMsgGroup(String msgGroup) {
+ this.msgGroup = msgGroup;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/dao/SmsRecordDao.java b/src/main/java/com/fr/plugin/nnsz/sms/dao/SmsRecordDao.java
new file mode 100644
index 0000000..9e624e2
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/dao/SmsRecordDao.java
@@ -0,0 +1,21 @@
+package com.fr.plugin.nnsz.sms.dao;
+
+import com.fr.plugin.nnsz.sms.entity.SmsRecord;
+import com.fr.stable.db.dao.BaseDAO;
+import com.fr.stable.db.session.DAOSession;
+
+/**
+ * @Author fr.open
+ * @Date 2020/11/5
+ * @Description
+ **/
+public class SmsRecordDao extends BaseDAO {
+ public SmsRecordDao(DAOSession daoSession) {
+ super(daoSession);
+ }
+
+ @Override
+ protected Class getEntityClass() {
+ return SmsRecord.class;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/nnsz/sms/entity/SmsRecord.java b/src/main/java/com/fr/plugin/nnsz/sms/entity/SmsRecord.java
new file mode 100644
index 0000000..7324b5b
--- /dev/null
+++ b/src/main/java/com/fr/plugin/nnsz/sms/entity/SmsRecord.java
@@ -0,0 +1,75 @@
+package com.fr.plugin.nnsz.sms.entity;
+
+import com.fr.stable.db.entity.BaseEntity;
+import com.fr.third.javax.persistence.Column;
+import com.fr.third.javax.persistence.Entity;
+import com.fr.third.javax.persistence.Table;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * @Author fr.open
+ * @Date 2020/11/5
+ * @Description
+ **/
+@Entity
+@Table(name = "plugin_nnsz_sms_record")
+public class SmsRecord extends BaseEntity {
+
+ @Column(name = "send_url")
+ private String url;
+ @Column(name = "mobile")
+ private String mobile;
+ @Column(name = "content",length = 2000)
+ private String content;
+ @Column(name = "sendTime")
+ private Date sendTime;
+ @Column(name = "send_result",length = 2000)
+ private String result;
+
+ public SmsRecord() {
+ this.setId(UUID.randomUUID().toString());
+ this.sendTime = new Date();
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+ public void setResult(String result) {
+ this.result = result;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getMobile() {
+ return mobile;
+ }
+
+ public void setMobile(String mobile) {
+ this.mobile = mobile;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public Date getSendTime() {
+ return sendTime;
+ }
+
+ public void setSendTime(Date sendTime) {
+ this.sendTime = sendTime;
+ }
+}
diff --git a/src/main/resources/conf.properties b/src/main/resources/conf.properties
new file mode 100644
index 0000000..e043bbc
--- /dev/null
+++ b/src/main/resources/conf.properties
@@ -0,0 +1,6 @@
+ecName=xxxx
+apId=xxx
+secretKey=xxxx
+sign=xxxxx
+addSerial=
+url=http://xxxx/sms/norsubmit
\ No newline at end of file