diff --git a/README.md b/README.md
index 58f1308..4f9abed 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-9330
-JSD-9330 第三方短信集成
\ No newline at end of file
+JSD-9330 第三方短信集成\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar
new file mode 100644
index 0000000..611c8f5
Binary files /dev/null and b/lib/finekit-10.0.jar differ
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..87f4db3
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,22 @@
+
+
+ com.fr.plugin.third.party.jsdjdda
+
+ yes
+ 0.4
+ 10.0
+ 2019-01-01
+ fr.open
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/CustomSMSService.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/CustomSMSService.java
new file mode 100644
index 0000000..4289f50
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/CustomSMSService.java
@@ -0,0 +1,294 @@
+package com.fr.plugin.third.party.jsdjdda;
+
+import com.fanruan.api.log.LogKit;
+import com.fanruan.api.util.StringKit;
+import com.fr.json.JSONArray;
+import com.fr.json.JSONObject;
+import com.fr.plugin.third.party.jsdjdda.config.CustomDataConfig;
+import com.fr.stable.fun.impl.AbstractSMSServiceProvider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CustomSMSService extends AbstractSMSServiceProvider {
+ private static Map BUILD_IN_TEMPLATE_MAP = new HashMap<>();
+ private static Map BUILD_IN_TEMPLATE_ID_MAP = new HashMap<>();
+
+ static {
+ BUILD_IN_TEMPLATE_MAP.put("10", "尊敬的管理员,#taskname#于#time#运行失败,请知晓。");
+ BUILD_IN_TEMPLATE_MAP.put("11", "尊敬的#name#,您有一个工单号为:#order_number#的待处理工单,请您及时处理!");
+ BUILD_IN_TEMPLATE_MAP.put("13", "您好,#webname#系统内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。");
+ BUILD_IN_TEMPLATE_MAP.put("14", "尊敬的管理员,#taskname#于#time#运行失败,请知晓。");
+ BUILD_IN_TEMPLATE_MAP.put("15", "您好,#taskname#于#time#运行成功。");
+ BUILD_IN_TEMPLATE_MAP.put("16", "您的手机验证码为#Verifiecode#,请于10分钟内正确输入。");
+ BUILD_IN_TEMPLATE_MAP.put("17", "您好,#webname#系统内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。");
+ BUILD_IN_TEMPLATE_MAP.put("18", "恭喜!您的短信服务已经配置成功。");
+ BUILD_IN_TEMPLATE_MAP.put("20", "您的手机验证码为#verifiecode#,请于10分钟内正确输入。");
+ BUILD_IN_TEMPLATE_MAP.put("49", "您好,#webname#系统日志文件已大于#logsize#M,请及时登录平台进行日志清理。");
+ BUILD_IN_TEMPLATE_MAP.put("50", "您好,#webname#系统#clustername#内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。");
+ BUILD_IN_TEMPLATE_MAP.put("51", "你好,#task#出错,请及时处理。该任务开始执行时间:#time#");
+ BUILD_IN_TEMPLATE_MAP.put("53", "上报任务 #task#,已经到您这里#time#,请尽快处理!");
+ BUILD_IN_TEMPLATE_MAP.put("54", "#name#您好,上报任务#task#已经发起,请尽快处理!");
+ BUILD_IN_TEMPLATE_MAP.put("63", "节点#nodename2#,与节点#nodename1#系统时间相差超过#time_different#秒,为避免影响用户使用,请及时调整使各节点时间保持一致。");
+ BUILD_IN_TEMPLATE_MAP.put("64", "节点#nodename#已脱离集群环境,可能原因为:节点FullGC、节点宕机、节点间通信不畅、节点负载过高、其他异常。为避免影响用户使用,请及时检查该节点状态,若该节点长时间无法自行恢复,则建议重启该节点。");
+ BUILD_IN_TEMPLATE_MAP.put("89", "节点#nodename#,与节点#node1name#的jar包不一致,将影响集群工程的稳定性,请前往集群节点管理页面查看详细异常信息,并及时处理。");
+ BUILD_IN_TEMPLATE_MAP.put("90", "节点#nodename#情况异常,用户不能正常访问,请及时检查该节点状态。");
+ BUILD_IN_TEMPLATE_MAP.put("125", "您有个#proname#任务即将过期,请您尽快办理。");
+ BUILD_IN_TEMPLATE_MAP.put("127", "您有个#proname#任务需要处理,请您尽快办理。发起人:#startpeople#,发起时间:#starttime#。");
+ BUILD_IN_TEMPLATE_MAP.put("134", "Redis集群#ip_port#节点已无法正常使用,可能原因为:节点宕机、内存已满、其他异常。为避免影响用户使用,请前往状态服务器配置页面查看详情,并及时处理。");
+ BUILD_IN_TEMPLATE_MAP.put("135", "文件服务器出现无法读写的情况,可能原因为:文件服务器宕机、磁盘已满、其他异常。为避免影响用户使用,请及时检查文件服务器状态。");
+ BUILD_IN_TEMPLATE_MAP.put("136", "您好,#webname#系统#clustername#当前负载状态过高,可能存在宕机风险,请及时关注。建议使用管理系统-智能运维-云端运维功能分析当前系统存在的性能问题。");
+ BUILD_IN_TEMPLATE_MAP.put("239", "您好,预警任务#warningname#达到阈值被触发,请及时关注!模板路径:#templatePath#");
+ BUILD_IN_TEMPLATE_MAP.put("264", "更新任务「#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#。");
+ BUILD_IN_TEMPLATE_MAP.put("265", "报表系统已宕机,请访问运维工具关注问题处理状态或及时进行系统重启。");
+ BUILD_IN_TEMPLATE_MAP.put("266", "报表系统已宕机,自动重启系统失败,请及时进行手动重启。");
+ BUILD_IN_TEMPLATE_MAP.put("269", "检查到系统环境配置存有不合理项,请及时查看并改正不合理项。");
+ BUILD_IN_TEMPLATE_MAP.put("276", "你好,[#taskname#]备份失败,请及时处理,备份时间:#time#");
+ BUILD_IN_TEMPLATE_MAP.put("367", "集群节点#node_name#与基准节点存在不一致文件,且无法自动同步。请检查该节点状态");
+ BUILD_IN_TEMPLATE_MAP.put("368", "集群节点#node_name#与基准节点存在不一致文件,已自动同步与基准节点一致,不一致文件备份在该节点工程WEB-INF/#directory#/下");
+ BUILD_IN_TEMPLATE_MAP.put("509", "尊敬的管理员,用户管理-同步用户于#time#运行失败,可手动触发同步,以查看详细报错。");
+ BUILD_IN_TEMPLATE_MAP.put("550", "Dear administrator, \"User>Sync user\" failed to run at #time#, you can trigger the sync manually to view the detailed error report.");
+ BUILD_IN_TEMPLATE_MAP.put("551", "尊敬的管理員,使用者管理-同步使用者於#time#執行失敗,可手動觸發同步,以檢視詳細報錯。");
+ BUILD_IN_TEMPLATE_MAP.put("573", "您好,#etltask# 运行失败,开始执行时间为 #begintime#,结束时间为 #endtime#,请前往 [数据准备]-[ETL作业]-[任务运维] 查看详情。");
+ BUILD_IN_TEMPLATE_MAP.put("587", "您好,检测到系统有宕机记录,请访问管理系统——智能运维——宕机处理页面中的宕机自助向导,查看宕机原因,并依据推荐解决方案进行处理");
+ BUILD_IN_TEMPLATE_MAP.put("600", "尊敬的#name#,#taskname#于#time#已更新,请及时关注。");
+ BUILD_IN_TEMPLATE_MAP.put("602", "#date#日有#templatecount#张模板在使用中出现共#errorcount#次报错,请至智能运维-平台日志中查看并处理模板报错。");
+ BUILD_IN_TEMPLATE_MAP.put("605", "您好,#webname#中,生成数据-定时计算任务“#taskname#”执行异常,生成数据失败。请及时登录系统处理");
+ BUILD_IN_TEMPLATE_MAP.put("606", "您好,#webname#中,生成数据-定时计算任务“#taskname#”执行成功,已完成#dataTypeText#(#dateRangeText#)数据计算");
+ BUILD_IN_TEMPLATE_MAP.put("998", "节点#nodename1#与节点#nodename2#之间通信异常,无法加入节点管理,请检查集群节点间通信端口是否已开放[TCP:7800,7810, 7820,7830, 7840, 7850,7860,7870][UDP:45588~65536 随机端口]。");
+ BUILD_IN_TEMPLATE_MAP.put("999", "节点#node_name#的#type#模块存在异常,暂无法正常提供服务,请及时对异常状况进行排查");
+
+ BUILD_IN_TEMPLATE_ID_MAP.put("10", "10");
+ BUILD_IN_TEMPLATE_ID_MAP.put("11", "11");
+ BUILD_IN_TEMPLATE_ID_MAP.put("13", "13");
+ BUILD_IN_TEMPLATE_ID_MAP.put("14", "14");
+ BUILD_IN_TEMPLATE_ID_MAP.put("15", "15");
+ BUILD_IN_TEMPLATE_ID_MAP.put("16", "16");
+ BUILD_IN_TEMPLATE_ID_MAP.put("17", "17");
+ BUILD_IN_TEMPLATE_ID_MAP.put("18", "18");
+ BUILD_IN_TEMPLATE_ID_MAP.put("20", "20");
+ BUILD_IN_TEMPLATE_ID_MAP.put("49", "49");
+ BUILD_IN_TEMPLATE_ID_MAP.put("50", "50");
+ BUILD_IN_TEMPLATE_ID_MAP.put("51", "51");
+ BUILD_IN_TEMPLATE_ID_MAP.put("53", "53");
+ BUILD_IN_TEMPLATE_ID_MAP.put("54", "54");
+ BUILD_IN_TEMPLATE_ID_MAP.put("63", "63");
+ BUILD_IN_TEMPLATE_ID_MAP.put("64", "64");
+ BUILD_IN_TEMPLATE_ID_MAP.put("89", "89");
+ BUILD_IN_TEMPLATE_ID_MAP.put("90", "90");
+ BUILD_IN_TEMPLATE_ID_MAP.put("125", "125");
+ BUILD_IN_TEMPLATE_ID_MAP.put("127", "127");
+ BUILD_IN_TEMPLATE_ID_MAP.put("134", "134");
+ BUILD_IN_TEMPLATE_ID_MAP.put("135", "135");
+ BUILD_IN_TEMPLATE_ID_MAP.put("136", "136");
+ BUILD_IN_TEMPLATE_ID_MAP.put("239", "239");
+ BUILD_IN_TEMPLATE_ID_MAP.put("264", "264");
+ BUILD_IN_TEMPLATE_ID_MAP.put("265", "265");
+ BUILD_IN_TEMPLATE_ID_MAP.put("266", "266");
+ BUILD_IN_TEMPLATE_ID_MAP.put("269", "269");
+ BUILD_IN_TEMPLATE_ID_MAP.put("276", "276");
+ BUILD_IN_TEMPLATE_ID_MAP.put("367", "367");
+ BUILD_IN_TEMPLATE_ID_MAP.put("368", "368");
+ BUILD_IN_TEMPLATE_ID_MAP.put("509", "509");
+ BUILD_IN_TEMPLATE_ID_MAP.put("550", "550");
+ BUILD_IN_TEMPLATE_ID_MAP.put("551", "551");
+ BUILD_IN_TEMPLATE_ID_MAP.put("573", "573");
+ BUILD_IN_TEMPLATE_ID_MAP.put("587", "587");
+ BUILD_IN_TEMPLATE_ID_MAP.put("600", "600");
+ BUILD_IN_TEMPLATE_ID_MAP.put("602", "602");
+ BUILD_IN_TEMPLATE_ID_MAP.put("605", "605");
+ BUILD_IN_TEMPLATE_ID_MAP.put("606", "606");
+ BUILD_IN_TEMPLATE_ID_MAP.put("998", "998");
+ BUILD_IN_TEMPLATE_ID_MAP.put("999", "999");
+
+ }
+
+ /**
+ * 根据内置的短信模板编号,转换成实际的第三方短信平台的短信模板
+ *
+ * @return 编号和实际模板的键值对集合
+ */
+ @Override
+ public Map mapping() {
+ return BUILD_IN_TEMPLATE_ID_MAP;
+ }
+
+ /**
+ * 发送测试短信
+ *
+ * @param mobile 接收短信的手机号
+ * @return 结果
+ */
+ @Override
+ public Response sendTest(String mobile) {
+ String buildInTemplateId = "18";
+ try {
+ List mobiles = SmsUtils.createMobiles(mobile, null);
+ String templateId = getCustomTemplateId(buildInTemplateId);
+ SmsUtils.sendSms(mobiles, templateId, null);
+ } catch (Exception e) {
+ LogKit.error("短信集成,发送测试短信出错,"+ e.getMessage());
+ }
+ String msg = createSmsContent(buildInTemplateId, null);
+ Response response = Response.create(Response.RES_STATUS_SUCCESS, msg, null);
+ return response;
+ }
+
+ /**
+ * FR包含的短信发送功能
+ *
+ * @param template 发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
+ * @param mobile 接收短信的手机号
+ * @param para 生成最终短信需要的参数
+ * @param receiver 接收者(用户)
+ * @return 结果
+ * @throws Exception 异常
+ */
+ @Override
+ public Response send(String template, String mobile, JSONObject para, String receiver) throws Exception {
+ List mobiles = SmsUtils.createMobiles(mobile, receiver);
+ String templateId = getCustomTemplateId(template);
+ List params = getJsonValues(para);
+ SmsUtils.sendSms(mobiles, templateId, params);
+ List userNames = SmsUtils.createUserNames(receiver);
+ SmsUtils.sendMsgByAccount(userNames, templateId, params);
+ String msg = createSmsContent(template, para);
+ Response response = Response.create(Response.RES_STATUS_SUCCESS, msg, null);
+ return response;
+ }
+
+ /**
+ * FR包含的批量发送短信的功能
+ *
+ * @param template 发送短信的模板(里面有参数,需要根据后面的para里的参数值进行替换)
+ * @param mobiles 接收短信的手机号列表
+ * @param params 对应的生成最终短信需要的参数JSON数组
+ * @param receivers 接收者(用户)列表,三个列表/数组,根据序号一一对应
+ * @return 结果
+ * @throws Exception 异常
+ */
+ @Override
+ public Response batchSendSMS(String template, List mobiles, JSONArray params, List receivers) throws Exception {
+ //SMSManager.getInstance();
+ //SMSService.getInstance().getSMSInfo();
+ String msg = "短信集成,不支持batchSendSMS";
+ LogKit.info(msg);
+
+ Response response = Response.create(Response.RES_STATUS_FAILED, msg, null);
+ return response;
+ }
+
+
+ private String createSmsContent(String templateId, JSONObject para) {
+ if (StringKit.isEmpty(templateId)) {
+ return "";
+ }
+
+ if (!BUILD_IN_TEMPLATE_MAP.containsKey(templateId)) {
+ return "";
+ }
+
+ String content = BUILD_IN_TEMPLATE_MAP.get(templateId);
+ if (StringKit.isEmpty(content)) {
+ content = "";
+ }
+ if (para == null) {
+ return content;
+ }
+
+ List fieldNames = new ArrayList<>();
+ fieldNames.addAll(para.fieldNames());
+ int size = fieldNames.size();
+ if (size <= 0) {
+ return content;
+ }
+ String name, value;
+ for (int i = 0, max = size - 1; i <= max; i++) {
+ name = fieldNames.get(i);
+ value = para.getString(name);
+ if (StringKit.isEmpty(value)) {
+ value = "";
+ }
+ content = content.replace(name, value);
+ }
+ return content;
+ }
+
+ private List getJsonValues(JSONObject json) {
+ List values = new ArrayList<>();
+ if (json == null) {
+ return values;
+ }
+
+ List fieldNames = new ArrayList<>();
+ fieldNames.addAll(json.fieldNames());
+ int size = fieldNames.size();
+ if (size <= 0) {
+ return values;
+ }
+ String name, value;
+ for (int i = 0, max = size - 1; i <= max; i++) {
+ name = fieldNames.get(i);
+ value = json.getString(name);
+ if (StringKit.isEmpty(value)) {
+ value = "";
+ }
+ values.add(value);
+ }
+ return values;
+ }
+
+
+ /**
+ * 获取定制的短信模板编号
+ *
+ * @param id
+ * @return
+ */
+ private String getCustomTemplateId(String id) {
+ if (StringKit.isEmpty(id)) {
+ return "";
+ }
+
+ String content = StringKit.trim(CustomDataConfig.getInstance().getTemplateMap());
+ if (StringKit.isEmpty(content)) {
+ return "";
+ }
+ String[] templateMaps = content.split(";");
+ if ((templateMaps == null) || (templateMaps.length <= 0)) {
+ return "";
+ }
+ String tempValue, tempValue1, tempValue2;
+
+ String[] templateIds;
+ for (int i = 0, max = templateMaps.length - 1; i <= max; i++) {
+ tempValue = StringKit.trim(templateMaps[i]);
+ if (StringKit.isEmpty(tempValue)) {
+ continue;
+ }
+
+ templateIds = tempValue.split(":");
+ if ((templateIds == null) || (templateIds.length <= 1)) {
+ continue;
+ }
+ tempValue1 = StringKit.trim(templateIds[0]);
+ tempValue2 = StringKit.trim(templateIds[1]);
+ if (StringKit.isEmpty(tempValue1) || StringKit.isEmpty(tempValue2)) {
+ continue;
+ }
+ if (StringKit.equals(tempValue1, id)) {
+ return tempValue2;
+ }
+ }
+ return "";
+ }
+
+
+
+
+
+
+
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/SmsUtils.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/SmsUtils.java
new file mode 100644
index 0000000..7cdfc2b
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/SmsUtils.java
@@ -0,0 +1,272 @@
+package com.fr.plugin.third.party.jsdjdda;
+
+import com.fanruan.api.log.LogKit;
+import com.fanruan.api.util.StringKit;
+import com.fr.decision.authority.AuthorityContext;
+import com.fr.decision.authority.data.User;
+import com.fr.json.JSONArray;
+import com.fr.json.JSONObject;
+import com.fr.plugin.context.PluginContexts;
+import com.fr.plugin.third.party.jsdjdda.config.CustomDataConfig;
+import com.fr.stable.StringUtils;
+import com.fr.stable.query.QueryFactory;
+import com.fr.stable.query.restriction.RestrictionFactory;
+import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
+import com.fr.third.org.apache.http.client.methods.HttpPost;
+import com.fr.third.org.apache.http.entity.StringEntity;
+import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class SmsUtils {
+
+ /**
+ * 根据手机号发送短信消息
+ *
+ * @param mobiles 手机号
+ * @param templateId 模板编号
+ * @param params 参数
+ * @throws IOException
+ */
+ public static synchronized void sendSms(List mobiles, String templateId, List params) throws Exception {
+ if ((mobiles == null) || (mobiles.size() <= 0) || (StringKit.isEmpty(templateId))) {
+ return;
+ }
+ if (params == null) {
+ params = new ArrayList<>();
+ }
+
+ if (true) {
+ LogKit.info("短信集成,根据手机号发送短信消息,mobiles:" + mobiles);
+ LogKit.info("短信集成,根据手机号发送短信消息,templateId:" + templateId);
+ LogKit.info("短信集成,根据手机号发送短信消息,params:" + params);
+ //return;
+ }
+
+ //添加认证
+ if (!PluginContexts.currentContext().isAvailable()) {
+ LogKit.error("短信集成,许可证过期失效");
+ return;
+ }
+
+ String smsUrl = CustomDataConfig.getInstance().getSmsUrl();
+ String appId = CustomDataConfig.getInstance().getAppId();
+ if (StringKit.isEmpty(smsUrl) || StringKit.isEmpty(appId)) {
+ return;
+ }
+
+ CloseableHttpClient httpClient = Utils.createHttpClient(smsUrl);
+ HttpPost httpPost = new HttpPost(smsUrl);
+ httpPost.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT);
+ httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
+ httpPost.addHeader("apikey", CustomDataConfig.getInstance().getApiKey());
+ httpPost.setConfig(Utils.REQUEST_CONFIG);
+
+
+ /*
+ {
+ "appid": "498de05d-0700-420d-9867-612823212573",
+ "mobile": "13100000000",
+ "templateid": 334336,
+ "params": [
+ "流程",
+ "提醒0522"
+ ]
+}
+ * */
+
+
+ JSONArray paramsJson = new JSONArray();
+ for (int i = 0, max = params.size() - 1; i <= max; i++) {
+ paramsJson.add(params.get(i));
+ }
+
+ JSONObject bodyJson = new JSONObject();
+ bodyJson.put("appid", appId);
+ bodyJson.put("templateid", Integer.valueOf(StringKit.trim(templateId)));
+ bodyJson.put("params", paramsJson);
+
+ StringEntity bodyEntity;
+ String mobile;
+ CloseableHttpResponse response;
+ String bodyContent;
+ for (int i = 0, max = mobiles.size() - 1; i <= max; i++) {
+ mobile = mobiles.get(i);
+ bodyJson.put("mobile", mobile);
+ bodyContent = bodyJson.toString();
+ LogKit.info("短信集成,根据手机号发送短信消息请求体:" + bodyContent);
+ bodyEntity = new StringEntity(bodyContent, "UTF-8");
+ httpPost.setEntity(bodyEntity);
+ response = httpClient.execute(httpPost);
+ LogKit.info("短信集成,根据手机号发送短信消息响应status:" + response.getStatusLine().getStatusCode() + "\n" + Utils.getHttpResponseBody(response));
+ response.close();
+ }
+ httpClient.close();
+ }
+
+ /**
+ * 根据账号发送消息
+ *
+ * @param accounts
+ * @param templateId
+ * @param params
+ * @throws Exception
+ */
+ public static synchronized void sendMsgByAccount(List accounts, String templateId, List params) throws Exception {
+ if ((accounts == null) || (accounts.size() <= 0) || (StringKit.isEmpty(templateId))) {
+ return;
+ }
+ if (params == null) {
+ params = new ArrayList<>();
+ }
+
+ if (true) {
+ LogKit.info("短信集成,根据账号发送消息,accounts:" + accounts);
+ LogKit.info("短信集成,根据账号发送消息,templateId:" + templateId);
+ LogKit.info("短信集成,根据账号发送消息,params:" + params);
+ //return;
+ }
+
+ //添加认证
+ if (!PluginContexts.currentContext().isAvailable()) {
+ LogKit.error("短信集成,许可证过期失效");
+ return;
+ }
+
+ String smsUrl = CustomDataConfig.getInstance().getAccountSmsUrl();
+ String appId = CustomDataConfig.getInstance().getAppId();
+ if (StringKit.isEmpty(smsUrl) || StringKit.isEmpty(appId)) {
+ return;
+ }
+
+ CloseableHttpClient httpClient = Utils.createHttpClient(smsUrl);
+ HttpPost httpPost = new HttpPost(smsUrl);
+ httpPost.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT);
+ httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
+ httpPost.addHeader("apikey", CustomDataConfig.getInstance().getApiKey());
+ httpPost.setConfig(Utils.REQUEST_CONFIG);
+
+
+ /*
+ {
+ "appid": "498de05d-0700-420d-9867-612823212573",
+ "mobile": "13100000000",
+ "templateid": 334336,
+ "params": [
+ "流程",
+ "提醒0522"
+ ]
+}
+ * */
+
+
+ JSONArray paramsJson = new JSONArray();
+ for (int i = 0, max = params.size() - 1; i <= max; i++) {
+ paramsJson.add(params.get(i));
+ }
+
+ JSONObject bodyJson = new JSONObject();
+ bodyJson.put("appid", appId);
+ bodyJson.put("templateid", Integer.valueOf(StringKit.trim(templateId)));
+ bodyJson.put("params", paramsJson);
+ bodyJson.put("url", "");
+
+ StringEntity bodyEntity;
+ String account;
+ CloseableHttpResponse response;
+ String bodyContent;
+ for (int i = 0, max = accounts.size() - 1; i <= max; i++) {
+ account = accounts.get(i);
+ bodyJson.put("account", account);
+ bodyContent = bodyJson.toString();
+ LogKit.info("短信集成,根据账号发送消息请求体:" + bodyContent);
+ bodyEntity = new StringEntity(bodyContent, "UTF-8");
+ httpPost.setEntity(bodyEntity);
+ response = httpClient.execute(httpPost);
+ LogKit.info("短信集成,根据账号发送消息响应status:" + response.getStatusLine().getStatusCode() + "\n" + Utils.getHttpResponseBody(response));
+ response.close();
+ }
+ httpClient.close();
+ }
+
+ public static List createMobiles(String mobile, String userName) throws Exception {
+ List mobiles = new ArrayList<>();
+ mobiles.add(mobile);
+ List userNames = new ArrayList<>();
+ userNames.add(userName);
+ return createMobiles(mobiles, userNames);
+ }
+
+ public static List createMobiles(List mobiles, List userNames) throws Exception {
+ Set allMobileSet = new HashSet<>();
+ Set mobileSet = createSet(mobiles);
+ Set userMobileSet = createSet(createUserMobiles(userNames));
+ allMobileSet.addAll(mobileSet);
+ allMobileSet.addAll(userMobileSet);
+ List allMobiles = new ArrayList<>();
+ allMobiles.addAll(allMobileSet);
+ return allMobiles;
+ }
+
+ public static List createUserNames(String userName) throws Exception {
+ List userNames = new ArrayList<>();
+ if (StringKit.isEmpty(userName)) {
+ return userNames;
+ }
+ userNames.add(userName);
+ return createUserNames(userNames);
+ }
+
+ public static List createUserNames(List userNames) throws Exception {
+ Set userSet = createSet(userNames);
+ List allUserNames = new ArrayList<>();
+ allUserNames.addAll(userSet);
+ return allUserNames;
+ }
+
+
+ public static Set createSet(List values) {
+ Set valueSet = new HashSet();
+ if ((values == null) || (values.size() <= 0)) {
+ return valueSet;
+ }
+
+ String value;
+ List tempValues = new ArrayList<>();
+ tempValues.addAll(values);
+ for (int i = 0, max = tempValues.size() - 1; i <= max; i++) {
+ value = StringKit.trim(tempValues.get(i));
+ if (StringKit.isEmpty(value)) {
+ continue;
+ }
+ valueSet.add(value);
+ }
+ return valueSet;
+ }
+
+ public static List createUserMobiles(List userNames) throws Exception {
+ if ((userNames == null) || (userNames.size() <= 0)) {
+ return new ArrayList<>();
+ }
+ Set userSet = new HashSet();
+ String userName;
+ for (int i = 0, max = userNames.size() - 1; i <= max; i++) {
+ userName = StringKit.trim(userNames.get(i));
+ if (StringKit.isEmpty(userName)) {
+ continue;
+ }
+ userSet.add(userName);
+ }
+ if (userSet.size() <= 0) {
+ return new ArrayList<>();
+ }
+ List userList = AuthorityContext.getInstance().getUserController().find(QueryFactory.create().addRestriction(RestrictionFactory.in("userName", userSet)));
+ List sysMobiles = userList.stream().filter(e -> StringUtils.isNotBlank(e.getMobile())).map(e -> e.getMobile()).collect(Collectors.toList());
+ return sysMobiles;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/Utils.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/Utils.java
new file mode 100644
index 0000000..6ca7714
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/Utils.java
@@ -0,0 +1,172 @@
+package com.fr.plugin.third.party.jsdjdda;
+
+import com.fanruan.api.log.LogKit;
+import com.fanruan.api.util.StringKit;
+import com.fr.general.IOUtils;
+import com.fr.third.org.apache.http.HttpEntity;
+import com.fr.third.org.apache.http.HttpStatus;
+import com.fr.third.org.apache.http.client.config.RequestConfig;
+import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
+import com.fr.third.org.apache.http.client.methods.HttpGet;
+import com.fr.third.org.apache.http.client.methods.HttpPost;
+import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier;
+import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import com.fr.third.org.apache.http.entity.StringEntity;
+import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
+import com.fr.third.org.apache.http.impl.client.HttpClients;
+import com.fr.third.org.apache.http.ssl.SSLContextBuilder;
+import com.fr.third.org.apache.http.ssl.TrustStrategy;
+import com.fr.third.org.apache.http.util.EntityUtils;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+public class Utils {
+ public static String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36";
+ public static RequestConfig REQUEST_CONFIG = RequestConfig.custom()
+ .setConnectionRequestTimeout(30000)
+ .setSocketTimeout(30000) // 服务端相应超时
+ .setConnectTimeout(30000) // 建立socket链接超时时间
+ .build();
+
+ public static CloseableHttpClient createSSLClientDefault() {
+ try {
+ SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
+
+ @Override
+ public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ return true;
+ }
+ }).build();
+ HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
+ SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
+ return HttpClients.custom().setSSLSocketFactory(sslsf).build();
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ return HttpClients.createDefault();
+ }
+
+ public static synchronized CloseableHttpClient createHttpClient(String url) {
+ CloseableHttpClient httpClient = null;
+ if (StringKit.isEmpty(url)) {
+ httpClient = HttpClients.createDefault();
+ return httpClient;
+ }
+
+ if (url.startsWith("https://")) {
+ httpClient = createSSLClientDefault();
+ return httpClient;
+ }
+ httpClient = HttpClients.createDefault();
+ return httpClient;
+ }
+
+ public static synchronized String createHttpGetContent(CloseableHttpClient httpClient, String url) throws IOException {
+ if ((httpClient == null) || (StringKit.isEmpty(url))) {
+ return "";
+ }
+
+ HttpGet httpGet = new HttpGet(url);
+ httpGet.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT);
+ httpGet.setConfig(Utils.REQUEST_CONFIG);
+ CloseableHttpResponse response = httpClient.execute(httpGet);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ response.close();
+ LogKit.info("http请求出错,http status:" + statusCode);
+ return "";
+ }
+
+ HttpEntity httpEntity = response.getEntity();
+ if (httpEntity == null) {
+ response.close();
+ LogKit.info("http请求出错,http响应内容为空");
+ return "";
+ }
+ String responseContent = EntityUtils.toString(httpEntity, "UTF-8");
+ response.close();
+ if (StringKit.isEmpty(responseContent)) {
+ LogKit.info("http请求出错,http响应内容为空1");
+ return "";
+ }
+ return responseContent;
+ }
+
+ public static synchronized String createHttpPostContent(CloseableHttpClient httpClient, String url, String bodyContent) throws IOException {
+ if ((httpClient == null) || (StringKit.isEmpty(url)) || (StringKit.isEmpty(bodyContent))) {
+ return "";
+ }
+
+ HttpPost httpPost = new HttpPost(url);
+ httpPost.addHeader("User-Agent", Utils.DEFAULT_USER_AGENT);
+ httpPost.setConfig(Utils.REQUEST_CONFIG);
+ StringEntity bodyEntity = new StringEntity(bodyContent, "UTF-8");
+ httpPost.setEntity(bodyEntity);
+ CloseableHttpResponse response = httpClient.execute(httpPost);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ response.close();
+ LogKit.info("http请求出错,http status:" + statusCode);
+ return "";
+ }
+
+ HttpEntity httpEntity = response.getEntity();
+ if (httpEntity == null) {
+ response.close();
+ LogKit.info("http请求出错,http响应内容为空");
+ return "";
+ }
+ String responseContent = EntityUtils.toString(httpEntity, "UTF-8");
+ response.close();
+ if (StringKit.isEmpty(responseContent)) {
+ LogKit.info("http请求出错,http响应内容为空1");
+ return "";
+ }
+ return responseContent;
+ }
+
+ /**
+ * 获取请求主体内容
+ * @param req
+ * @return
+ * @throws IOException
+ */
+ public static String getHttpRequestBody(HttpServletRequest req) throws IOException {
+ if (req == null) {
+ return "";
+ }
+ ServletInputStream inputStream = req.getInputStream();
+ if (inputStream == null) {
+ return "";
+ }
+ String content = IOUtils.inputStream2String(inputStream);
+ if (StringKit.isEmpty(content)) {
+ return "";
+ }
+ return content;
+ }
+
+ public static String getHttpResponseBody(CloseableHttpResponse response) throws IOException {
+ if (response == null) {
+ return "";
+ }
+ HttpEntity httpEntity = response.getEntity();
+ if (httpEntity == null) {
+ return "";
+ }
+ String responseContent = EntityUtils.toString(httpEntity, "UTF-8");
+ String content = responseContent;
+ if (StringKit.isEmpty(content)) {
+ return "";
+ }
+ return content;
+ }
+
+
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/config/CustomDataConfig.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/config/CustomDataConfig.java
new file mode 100644
index 0000000..93c4977
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/config/CustomDataConfig.java
@@ -0,0 +1,103 @@
+package com.fr.plugin.third.party.jsdjdda.config;
+
+import com.fr.config.*;
+import com.fr.config.holder.Conf;
+import com.fr.config.holder.factory.Holders;
+
+/**
+ * 配置数据保存
+ */
+@Visualization(category = "短信集成配置")
+public class CustomDataConfig extends DefaultConfiguration {
+ public String getNameSpace() {
+ return this.getClass().getName();
+ }
+
+ private static volatile CustomDataConfig config = null;
+
+ public static CustomDataConfig getInstance() {
+ if (config == null) {
+ config = ConfigContext.getConfigInstance(CustomDataConfig.class);
+ }
+ return config;
+ }
+
+ @Identifier(value = "apiKey", name = "接口密钥(apikey)", description = "", status = Status.SHOW)
+ private Conf apiKey = Holders.simple("");
+
+ @Identifier(value = "appId", name = "发送来源应用ID(appid)", description = "", status = Status.SHOW)
+ private Conf appId = Holders.simple("");
+
+ @Identifier(value = "smsUrl", name = "根据手机号发送短信消息接口地址", description = "", status = Status.SHOW)
+ private Conf smsUrl = Holders.simple("");
+
+ @Identifier(value = "accountSmsUrl", name = "根据账号发送消息接口地址", description = "", status = Status.SHOW)
+ private Conf accountSmsUrl = Holders.simple("");
+
+
+ @Identifier(value = "templateMap", name = "报表平台内置短信与集成短信模板对应关系", description = "内置短信编号:短信模板编号;内置短信编号:短信模板编号", status = Status.SHOW)
+ private Conf templateMap = Holders.simple("");
+
+ public String getApiKey() {
+ return apiKey.get();
+ }
+
+ public void setApiKey(String apiKey) {
+ this.apiKey.set(apiKey);
+ }
+
+ public String getAccountSmsUrl() {
+ return accountSmsUrl.get();
+ }
+
+ public void setAccountSmsUrl(String accountSmsUrl) {
+ this.accountSmsUrl.set(accountSmsUrl);
+ }
+
+ @Identifier(value = "buildInMobiles", name = "报表平台内置短信发送手机号", description = "多个用逗号隔开(,)", status = Status.HIDE)
+ private Conf buildInMobiles = Holders.simple("");
+
+ public String getBuildInMobiles() {
+ return buildInMobiles.get();
+ }
+
+ public void setBuildInMobiles(String buildInMobiles) {
+ this.buildInMobiles.set(buildInMobiles);
+ }
+
+ public String getAppId() {
+ return appId.get();
+ }
+
+ public void setAppId(String appId) {
+ this.appId.set(appId);
+ }
+
+ public String getSmsUrl() {
+ return smsUrl.get();
+ }
+
+ public void setSmsUrl(String smsUrl) {
+ this.smsUrl.set(smsUrl);
+ }
+
+ public String getTemplateMap() {
+ return templateMap.get();
+ }
+
+ public void setTemplateMap(String templateMap) {
+ this.templateMap.set(templateMap);
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ CustomDataConfig cloned = (CustomDataConfig) super.clone();
+ cloned.apiKey = (Conf) apiKey.clone();
+ cloned.appId = (Conf) appId.clone();
+ cloned.smsUrl = (Conf) smsUrl.clone();
+ cloned.accountSmsUrl = (Conf) accountSmsUrl.clone();
+ cloned.templateMap = (Conf) templateMap.clone();
+ cloned.buildInMobiles = (Conf) buildInMobiles.clone();
+ return cloned;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/config/DataConfigInitializeMonitor.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/config/DataConfigInitializeMonitor.java
new file mode 100644
index 0000000..ee57eac
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/config/DataConfigInitializeMonitor.java
@@ -0,0 +1,29 @@
+package com.fr.plugin.third.party.jsdjdda.config;
+
+import com.fr.config.MarketConfig;
+import com.fr.intelli.record.Focus;
+import com.fr.intelli.record.Original;
+import com.fr.plugin.context.PluginContext;
+import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
+import com.fr.record.analyzer.EnableMetrics;
+import com.fr.stable.fun.Authorize;
+
+/**
+ * 配置信息初始化
+ */
+@EnableMetrics
+@Authorize(callSignKey = "com.fr.plugin.third.party.jsdjdda")
+public class DataConfigInitializeMonitor extends AbstractPluginLifecycleMonitor {
+ @Override
+ @Focus(id = "com.fr.plugin.third.party.jsdjdda", text = "plugin-jsdjdda", source = Original.PLUGIN)
+ public void afterRun(PluginContext pluginContext) {
+ CustomDataConfig.getInstance();
+ MarketConfig.getInstance().setSMSOpen(true);
+ //MarketConfig.getInstance().isSMSOpen() || !MarketConfig.getInstance().isSMSAppEnable()
+ }
+
+ @Override
+ public void beforeStop(PluginContext pluginContext) {
+
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/http/CustomHttpHandlerProvider.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/CustomHttpHandlerProvider.java
new file mode 100644
index 0000000..dff1e90
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/CustomHttpHandlerProvider.java
@@ -0,0 +1,13 @@
+package com.fr.plugin.third.party.jsdjdda.http;
+
+import com.fr.decision.fun.impl.AbstractHttpHandlerProvider;
+import com.fr.decision.fun.impl.BaseHttpHandler;
+
+public class CustomHttpHandlerProvider extends AbstractHttpHandlerProvider {
+ @Override
+ public BaseHttpHandler[] registerHandlers() {
+ return new BaseHttpHandler[]{
+ new SendSmsHttpHandler()
+ };
+ }
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/http/CustomURLAliasProvider.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/CustomURLAliasProvider.java
new file mode 100644
index 0000000..61a84c8
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/CustomURLAliasProvider.java
@@ -0,0 +1,14 @@
+package com.fr.plugin.third.party.jsdjdda.http;
+
+import com.fr.decision.fun.impl.AbstractURLAliasProvider;
+import com.fr.decision.webservice.url.alias.URLAlias;
+import com.fr.decision.webservice.url.alias.URLAliasFactory;
+
+public class CustomURLAliasProvider extends AbstractURLAliasProvider {
+ @Override
+ public URLAlias[] registerAlias() {
+ return new URLAlias[]{
+ URLAliasFactory.createPluginAlias("/jsdjdda/send/sms", "/jsdjdda/send/sms", true),
+ };
+ }
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/http/SendSmsHttpHandler.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/SendSmsHttpHandler.java
new file mode 100644
index 0000000..ed5b438
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/SendSmsHttpHandler.java
@@ -0,0 +1,173 @@
+package com.fr.plugin.third.party.jsdjdda.http;
+
+import com.fanruan.api.util.StringKit;
+import com.fr.decision.fun.impl.BaseHttpHandler;
+import com.fr.json.JSONArray;
+import com.fr.json.JSONObject;
+import com.fr.plugin.third.party.jsdjdda.SmsUtils;
+import com.fr.plugin.third.party.jsdjdda.Utils;
+import com.fr.third.springframework.web.bind.annotation.RequestMethod;
+import com.fr.web.utils.WebUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 发送短信
+ */
+public class SendSmsHttpHandler extends BaseHttpHandler {
+ private static String MSG_TYPE_MOBILE = "MOBILE";
+ private static String MSG_TYPE_ACCOUNT = "ACCOUNT";
+
+ @Override
+ public RequestMethod getMethod() {
+ return RequestMethod.POST;
+ }
+
+ @Override
+ public String getPath() {
+ return "/jsdjdda/send/sms";
+ }
+
+ @Override
+ public boolean isPublic() {
+ return true;
+ }
+
+ @Override
+ public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
+ res.setContentType("application/json; charset=utf-8");
+ String content = Utils.getHttpRequestBody(req);
+ if (StringKit.isEmpty(content)) {
+ WebUtils.printAsJSON(res, createFailureJson("请求内容为空"));
+ return;
+ }
+
+ JSONObject contentJson = new JSONObject(content);
+ String templateId = StringKit.trim(contentJson.getString("templateid", ""));
+ if (StringKit.isEmpty(templateId)) {
+ WebUtils.printAsJSON(res, createFailureJson("消息模板ID为空"));
+ return;
+ }
+
+ List params = createParams(contentJson);
+
+ String msgType = StringKit.trim(contentJson.getString("msgType", ""));
+ msgType = createMsgType(msgType);
+
+ if (MSG_TYPE_ACCOUNT.equalsIgnoreCase(msgType)) {
+ String account = StringKit.trim(contentJson.getString("account", ""));
+ if (StringKit.isEmpty(account)) {
+ WebUtils.printAsJSON(res, createFailureJson("接收人账号为空"));
+ return;
+ }
+
+ List accounts = creatMobiles(account);
+ if ((accounts == null) || (accounts.size() <= 0)) {
+ WebUtils.printAsJSON(res, createFailureJson("接收人账号为空1"));
+ return;
+ }
+
+ try {
+ SmsUtils.sendMsgByAccount(accounts, templateId, params);
+ } catch (Exception e) {
+ WebUtils.printAsJSON(res, createFailureJson(e.getMessage()));
+ return;
+ }
+ WebUtils.printAsJSON(res, createSuccessJson());
+ return;
+ }
+
+ String mobile = StringKit.trim(contentJson.getString("mobile", ""));
+ if (StringKit.isEmpty(mobile)) {
+ WebUtils.printAsJSON(res, createFailureJson("接收人手机号为空"));
+ return;
+ }
+
+ List mobiles = creatMobiles(mobile);
+ if ((mobiles == null) || (mobiles.size() <= 0)) {
+ WebUtils.printAsJSON(res, createFailureJson("接收人手机号为空1"));
+ return;
+ }
+
+
+ try {
+ SmsUtils.sendSms(mobiles, templateId, params);
+ } catch (Exception e) {
+ WebUtils.printAsJSON(res, createFailureJson(e.getMessage()));
+ return;
+ }
+ WebUtils.printAsJSON(res, createSuccessJson());
+ }
+
+ private List creatMobiles(String mobileContent) {
+ List mobiles = new ArrayList<>();
+ if (StringKit.isEmpty(mobileContent)) {
+ return mobiles;
+ }
+ String[] tempValues = mobileContent.split(",");
+ if ((tempValues == null) || (tempValues.length <= 0)) {
+ return mobiles;
+ }
+ List values = Arrays.asList(tempValues);
+ mobiles.addAll(SmsUtils.createSet(values));
+ return mobiles;
+ }
+
+ private List createParams(JSONObject contentJson) {
+ List params = new ArrayList<>();
+ if (contentJson == null) {
+ return params;
+ }
+ if (!contentJson.has("params")) {
+ return params;
+ }
+
+ Object valueObj = contentJson.getValue("params");
+ if (!(valueObj instanceof JSONArray)) {
+ params.add(String.valueOf(valueObj));
+ return params;
+ }
+
+ JSONArray jsonArray = (JSONArray) valueObj;
+
+ for (int i = 0, max = jsonArray.size() - 1; i <= max; i++) {
+ params.add(jsonArray.getString(i));
+ }
+ return params;
+ }
+
+ private String createMsgType(String type) {
+ String tempType = StringKit.trim(type);
+ if (StringKit.isEmpty(tempType)) {
+ return MSG_TYPE_MOBILE;
+ }
+
+ if (MSG_TYPE_ACCOUNT.equalsIgnoreCase(tempType)) {
+ return MSG_TYPE_ACCOUNT;
+ }
+
+ return MSG_TYPE_MOBILE;
+ }
+
+
+ private JSONObject createSuccessJson() {
+ return createResultJson("success", "成功");
+ }
+
+ private JSONObject createFailureJson(String msg) {
+ return createResultJson("failure", msg);
+ }
+
+ private JSONObject createResultJson(String status, String msg) {
+ JSONObject json = new JSONObject();
+ json.put("status", status);
+ json.put("msg", msg);
+ return json;
+ }
+
+
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/http/SessionGlobalRequestFilterProvider.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/SessionGlobalRequestFilterProvider.java
new file mode 100644
index 0000000..14f4e23
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/SessionGlobalRequestFilterProvider.java
@@ -0,0 +1,93 @@
+package com.fr.plugin.third.party.jsdjdda.http;
+
+import com.fanruan.api.log.LogKit;
+import com.fanruan.api.util.StringKit;
+import com.fr.base.sms.SMSManager;
+import com.fr.config.MarketConfig;
+import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+import com.fr.json.JSONObject;
+import com.fr.web.utils.WebUtils;
+
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+public class SessionGlobalRequestFilterProvider extends AbstractGlobalRequestFilterProvider {
+ @Override
+ public String filterName() {
+ return "com.fr.plugin.third.party.jsdjdda";
+ }
+
+ @Override
+ public String[] urlPatterns() {
+ return new String[]{"/decision", "/decision/*"};
+ }
+
+ @Override
+ public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
+ try {
+ String method = req.getMethod();
+ String reqUrl = req.getRequestURL().toString();
+ if (!"GET".equalsIgnoreCase(method)) {
+ filterChain.doFilter(req, res);
+ return;
+ }
+
+ if (reqUrl.endsWith("decision/v10/config/sms") || reqUrl.endsWith("decision/v10/config/sms")) {
+ String reqFullUrl = getRequestFullUrl(req);
+ LogKit.info("短信集成,请求:" + method + " " + reqFullUrl);
+ modifySmsConfig(req, res, filterChain);
+ return;
+ }
+
+ filterChain.doFilter(req, res);
+ } catch (Exception e) {
+ LogKit.error("短信集成出错," + e.getMessage(), e);
+ }
+ }
+
+ private void modifySmsConfig(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws Exception {
+ MarketConfig.getInstance().setSMSOpen(true);
+
+ UrlResponseWrapper wrapperResponse = new UrlResponseWrapper(res);//转换成代理类
+ // 这里只拦截返回,直接让请求过去,如果在请求前有处理,可以在这里处理
+ filterChain.doFilter(req, wrapperResponse);
+ JSONObject dataJson = new JSONObject();
+ dataJson.put("isSMSOpen", SMSManager.getInstance().isSMSFuncSupport());
+ dataJson.put("isSMSFuncSupport", SMSManager.getInstance().isSMSFuncSupport());
+ dataJson.put("balance", 999.0);
+ dataJson.put("accountType", 0);
+ dataJson.put("sign", signContent);
+ dataJson.put("isOnline", true);
+ dataJson.put("isSMSApplied", true);
+ dataJson.put("testRemain", 999);
+ dataJson.put("publicModel", publicModelContent);
+ dataJson.put("privateModel", "[]");
+ dataJson.put("username", "短信集成");
+ JSONObject configJson = new JSONObject();
+ configJson.put("data", dataJson);
+ res.setContentLength(-1);
+ WebUtils.printAsJSON(res, configJson);
+ }
+
+ private static String signContent = "[{\"sign\":\"【信息平台】\",\"id\":2,\"is_default\":true},{\"sign\":\"【帆软软件】\",\"id\":3,\"is_default\":true}]";
+ private static String publicModelContent = "[{\"language\":\"zh_CN\",\"id\":\"10\",\"content\":\"【信息平台】尊敬的管理员,#taskname#于#time#运行失败,请知晓。\"},{\"language\":\"zh_CN\",\"id\":\"11\",\"content\":\"【帆软软件】尊敬的#name#,您有一个工单号为:#order_number#的待处理工单,请您及时处理!\"},{\"language\":\"zh_CN\",\"id\":\"13\",\"content\":\"【帆软软件】您好,#webname#系统内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。\"},{\"language\":\"zh_CN\",\"id\":\"14\",\"content\":\"【帆软软件】尊敬的管理员,#taskname#于#time#运行失败,请知晓。\"},{\"language\":\"zh_CN\",\"id\":\"15\",\"content\":\"【帆软软件】您好,#taskname#于#time#运行成功。\"},{\"language\":\"zh_CN\",\"id\":\"16\",\"content\":\"【帆软软件】您的手机验证码为#Verifiecode#,请于10分钟内正确输入。\"},{\"language\":\"zh_CN\",\"id\":\"17\",\"content\":\"【信息平台】您好,#webname#系统内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。\"},{\"language\":\"zh_CN\",\"id\":\"18\",\"content\":\"【信息平台】恭喜!您的短信服务已经配置成功。\"},{\"language\":\"zh_CN\",\"id\":\"20\",\"content\":\"【信息平台】您的手机验证码为#verifiecode#,请于10分钟内正确输入。\"},{\"language\":\"zh_CN\",\"id\":\"49\",\"content\":\"【信息平台】您好,#webname#系统日志文件已大于#logsize#M,请及时登录平台进行日志清理。\"},{\"language\":\"zh_CN\",\"id\":\"50\",\"content\":\"【信息平台】您好,#webname#系统#clustername#内存持续#m#分钟内存高于#n#,可能存在宕机风险,请及时关注。\"},{\"language\":\"zh_CN\",\"id\":\"51\",\"content\":\"【信息平台】你好,#task#出错,请及时处理。该任务开始执行时间:#time#\"},{\"language\":\"zh_CN\",\"id\":\"53\",\"content\":\"【信息平台】上报任务 #task#,已经到您这里#time#,请尽快处理!\"},{\"language\":\"zh_CN\",\"id\":\"54\",\"content\":\"【信息平台】#name#您好,上报任务#task#已经发起,请尽快处理!\"},{\"language\":\"zh_CN\",\"id\":\"63\",\"content\":\"【信息平台】节点#nodename2#,与节点#nodename1#系统时间相差超过#time_different#秒,为避免影响用户使用,请及时调整使各节点时间保持一致。\"},{\"language\":\"zh_CN\",\"id\":\"64\",\"content\":\"【信息平台】节点#nodename#已脱离集群环境,可能原因为:节点FullGC、节点宕机、节点间通信不畅、节点负载过高、其他异常。为避免影响用户使用,请及时检查该节点状态,若该节点长时间无法自行恢复,则建议重启该节点。\"},{\"language\":\"zh_CN\",\"id\":\"89\",\"content\":\"【信息平台】节点#nodename#,与节点#node1name#的jar包不一致,将影响集群工程的稳定性,请前往集群节点管理页面查看详细异常信息,并及时处理。\"},{\"language\":\"zh_CN\",\"id\":\"90\",\"content\":\"【信息平台】节点#nodename#情况异常,用户不能正常访问,请及时检查该节点状态。\"},{\"language\":\"zh_CN\",\"id\":\"125\",\"content\":\"【信息平台】您有个#proname#任务即将过期,请您尽快办理。\"},{\"language\":\"zh_CN\",\"id\":\"127\",\"content\":\"【信息平台】您有个#proname#任务需要处理,请您尽快办理。发起人:#startpeople#,发起时间:#starttime#。\"},{\"language\":\"zh_CN\",\"id\":\"134\",\"content\":\"【信息平台】Redis集群#ip_port#节点已无法正常使用,可能原因为:节点宕机、内存已满、其他异常。为避免影响用户使用,请前往状态服务器配置页面查看详情,并及时处理。\"},{\"language\":\"zh_CN\",\"id\":\"135\",\"content\":\"【信息平台】文件服务器出现无法读写的情况,可能原因为:文件服务器宕机、磁盘已满、其他异常。为避免影响用户使用,请及时检查文件服务器状态。\"},{\"language\":\"zh_CN\",\"id\":\"136\",\"content\":\"【信息平台】您好,#webname#系统#clustername#当前负载状态过高,可能存在宕机风险,请及时关注。建议使用管理系统-智能运维-云端运维功能分析当前系统存在的性能问题。\"},{\"language\":\"zh_CN\",\"id\":\"239\",\"content\":\"【帆软软件】您好,预警任务#warningname#达到阈值被触发,请及时关注!模板路径:#templatePath#\"},{\"language\":\"zh_CN\",\"id\":\"264\",\"content\":\"【信息平台】更新任务「#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#。\"},{\"language\":\"zh_CN\",\"id\":\"265\",\"content\":\"【信息平台】报表系统已宕机,请访问运维工具关注问题处理状态或及时进行系统重启。\"},{\"language\":\"zh_CN\",\"id\":\"266\",\"content\":\"【信息平台】报表系统已宕机,自动重启系统失败,请及时进行手动重启。\"},{\"language\":\"zh_CN\",\"id\":\"269\",\"content\":\"【信息平台】检查到系统环境配置存有不合理项,请及时查看并改正不合理项。\"},{\"language\":\"zh_CN\",\"id\":\"276\",\"content\":\"【信息平台】你好,[#taskname#]备份失败,请及时处理,备份时间:#time#\"},{\"language\":\"zh_CN\",\"id\":\"367\",\"content\":\"【信息平台】集群节点#node_name#与基准节点存在不一致文件,且无法自动同步。请检查该节点状态\"},{\"language\":\"zh_CN\",\"id\":\"368\",\"content\":\"【信息平台】集群节点#node_name#与基准节点存在不一致文件,已自动同步与基准节点一致,不一致文件备份在该节点工程WEB-INF/#directory#/下\"},{\"language\":\"zh_CN\",\"id\":\"509\",\"content\":\"【信息平台】尊敬的管理员,用户管理-同步用户于#time#运行失败,可手动触发同步,以查看详细报错。\"},{\"language\":\"zh_CN\",\"id\":\"550\",\"content\":\"【信息平台】Dear administrator, \\\"User>Sync user\\\" failed to run at #time#, you can trigger the sync manually to view the detailed error report.\"},{\"language\":\"zh_CN\",\"id\":\"551\",\"content\":\"【信息平台】尊敬的管理員,使用者管理-同步使用者於#time#執行失敗,可手動觸發同步,以檢視詳細報錯。\"},{\"language\":\"zh_CN\",\"id\":\"573\",\"content\":\"【信息平台】您好,#etltask# 运行失败,开始执行时间为 #begintime#,结束时间为 #endtime#,请前往 [数据准备]-[ETL作业]-[任务运维] 查看详情。\"},{\"language\":\"zh_CN\",\"id\":\"587\",\"content\":\"【信息平台】您好,检测到系统有宕机记录,请访问管理系统——智能运维——宕机处理页面中的宕机自助向导,查看宕机原因,并依据推荐解决方案进行处理\"},{\"language\":\"zh_CN\",\"id\":\"600\",\"content\":\"【信息平台】尊敬的#name#,#taskname#于#time#已更新,请及时关注。\"},{\"language\":\"zh_CN\",\"id\":\"602\",\"content\":\"【信息平台】#date#日有#templatecount#张模板在使用中出现共#errorcount#次报错,请至智能运维-平台日志中查看并处理模板报错。\"},{\"language\":\"zh_CN\",\"id\":\"605\",\"content\":\"【信息平台】您好,#webname#中,生成数据-定时计算任务“#taskname#”执行异常,生成数据失败。请及时登录系统处理\"},{\"language\":\"zh_CN\",\"id\":\"606\",\"content\":\"【信息平台】您好,#webname#中,生成数据-定时计算任务“#taskname#”执行成功,已完成#dataTypeText#(#dateRangeText#)数据计算\"},{\"language\":\"zh_CN\",\"id\":\"998\",\"content\":\"【信息平台】节点#nodename1#与节点#nodename2#之间通信异常,无法加入节点管理,请检查集群节点间通信端口是否已开放[TCP:7800,7810, 7820,7830, 7840, 7850,7860,7870][UDP:45588~65536 随机端口]。\"},{\"language\":\"zh_CN\",\"id\":\"999\",\"content\":\"【信息平台】节点#node_name#的#type#模块存在异常,暂无法正常提供服务,请及时对异常状况进行排查\"}]";
+
+
+ private String getRequestFullUrl(HttpServletRequest req) {
+ if (req == null) {
+ return "";
+ }
+ String query = req.getQueryString();
+ if (StringKit.isEmpty(query) || "null".equalsIgnoreCase(query)) {
+ query = "";
+ } else {
+ query = "?" + query;
+ }
+ String url = req.getRequestURL().toString() + query;
+ return url;
+ }
+
+
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/http/UrlResponseWrapper.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/UrlResponseWrapper.java
new file mode 100644
index 0000000..eb42665
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/http/UrlResponseWrapper.java
@@ -0,0 +1,91 @@
+package com.fr.plugin.third.party.jsdjdda.http;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.WriteListener;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+import java.io.*;
+
+public class UrlResponseWrapper extends HttpServletResponseWrapper {
+ private ByteArrayOutputStream buffer = null;
+ private ServletOutputStream out = null;
+ private PrintWriter writer = null;
+
+ public UrlResponseWrapper(HttpServletResponse resp) throws IOException {
+ super(resp);
+ buffer = new ByteArrayOutputStream();// 真正存储数据的流
+ out = new WapperedOutputStream(buffer);
+ writer = new PrintWriter(new OutputStreamWriter(buffer));
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ return out;
+ }
+
+ @Override
+ public PrintWriter getWriter() throws UnsupportedEncodingException {
+ return writer;
+ }
+
+ @Override
+ public void flushBuffer() throws IOException {
+ if (out != null) {
+ out.flush();
+ }
+ if (writer != null) {
+ writer.flush();
+ }
+ }
+
+ @Override
+ public void reset() {
+ buffer.reset();
+ }
+
+ public byte[] getResponseData() throws IOException {
+ flushBuffer();
+ return buffer.toByteArray();
+ }
+
+ public String getContent() throws IOException{
+ flushBuffer();
+ return buffer.toString();
+ }
+
+ private class WapperedOutputStream extends ServletOutputStream {
+ private ByteArrayOutputStream bos = null;
+
+ public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
+ bos = stream;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ bos.write(b);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ bos.write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ bos.write(b, off, len);
+ }
+
+
+ @Override
+ public boolean isReady() {
+ return false;
+ }
+
+ @Override
+ public void setWriteListener(WriteListener writeListener) {
+
+ }
+
+
+ }
+}
diff --git a/src/main/java/com/fr/plugin/third/party/jsdjdda/test/Test1.java b/src/main/java/com/fr/plugin/third/party/jsdjdda/test/Test1.java
new file mode 100644
index 0000000..cb972e7
--- /dev/null
+++ b/src/main/java/com/fr/plugin/third/party/jsdjdda/test/Test1.java
@@ -0,0 +1,13 @@
+package com.fr.plugin.third.party.jsdjdda.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Test1 {
+ public static void main(String[] args) {
+ Map map = new HashMap<>();
+
+ System.out.println(map.get("111"));
+
+ }
+}