Commit 3e4de28d authored by qinxunjia's avatar qinxunjia

更改对接碧桂园接口

parent 99c7201b
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
<name>插件服务</name> <name>插件服务</name>
<description>DM hub集成插件服务</description> <description>DM hub集成插件服务</description>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
...@@ -36,7 +35,6 @@ ...@@ -36,7 +35,6 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- Spring-Mybatis -->
<dependency> <dependency>
<groupId>org.mybatis.spring.boot</groupId> <groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId> <artifactId>mybatis-spring-boot-starter</artifactId>
......
package com.bgy;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(" com.bgy.sms.repository.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package com.bgy.exception;
import com.bgy.sms.config.ResponseCode;
public class ServiceException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String msg;
private String code = "500";
public ServiceException(String msg) {
super(msg);
this.msg = msg;
}
public ServiceException(String msg, Throwable e) {
super(msg, e);
this.msg = msg;
}
public ServiceException(String msg, String code) {
super(msg);
this.msg = msg;
this.code = code;
}
public ServiceException(String msg, String code, Throwable e) {
super(msg, e);
this.msg = msg;
this.code = code;
}
public ServiceException(ResponseCode responseCode) {
super(responseCode.getMsg());
this.msg = responseCode.getMsg();
this.code = responseCode.getCode();
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
package com.bgy.sms.channel.api;
import com.alibaba.fastjson.JSONObject;
import com.bgy.sms.channel.bgy.dto.CLNotifyRequest;
import com.bgy.sms.channel.bgy.dto.ReportDto;
import com.bgy.sms.channel.bgy.service.BgySmsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RequestMapping("/byg/")
@RestController
public class BgyApi {
private static final Logger log = LoggerFactory.getLogger(BgyApi.class);
@PostMapping("/notify")
public String notify(@RequestParam CLNotifyRequest notifyInfo) {
log.info("创蓝异步通知接口入参:{}", JSONObject.toJSONString(notifyInfo));
String response = "success";
try {
// bgySmsService.asyncNotify(notifyInfo);
} catch (Exception e) {
log.error("处理创建模板异步通知异常:", e);
response = "fail";
}
log.info("创蓝异步通知接口出参:{}", response);
return response;
}
@GetMapping("/report")
public String report(ReportDto report) {
log.info("回送报告接口入参:{}", JSONObject.toJSONString(report));
String response = "success";
try {
// CLBizResponse responses = chuangLanSmsService.report(report);
} catch (Exception e) {
log.error("处理回执逻辑异常:", e);
response = "fail";
}
log.info("创蓝异步通知接口出参:{}", response);
return response;
}
}
package com.bgy.sms.channel.api;
import com.alibaba.fastjson.JSONObject;
import com.bgy.sms.channel.dto.*;
import com.bgy.sms.config.ResponseCode;
import com.bgy.sms.service.MessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping()
public class DmHubApi {
private static final Logger log = LoggerFactory.getLogger(DmHubApi.class);
@Autowired
private MessageService messageService;
/**
* 创建短信模板
*
* @return
*/
@PostMapping("/sms/template")
public DmHubTemplateResponse template(@RequestBody DmHubTemplateRequest params) {
log.info("**********创建模板接口入参*******:{}", JSONObject.toJSONString(params));
DmHubTemplateResponse template;
try {
template = messageService.createTemplate(params);
} catch (Exception e) {
log.error("创建模板短信异常", e);
template = new DmHubTemplateResponse(ResponseCode.SYSTEM_ERROR);
}
log.info("**********创建模板接口出参*******:{}", JSONObject.toJSONString(template));
return template;
}
/**
* 批量发送(通知或营销类)
*
* @return
*/
@PostMapping("/sms/batch")
public DmHubSendResponse batch(@RequestBody DmHubBatchSendRequest request) {
log.info("**********批量发送入参*******:{}", JSONObject.toJSONString(request));
DmHubSendResponse response;
try {
response = messageService.batchSendOneByOne(request);
} catch (Exception e) {
log.error("发送批量短信异常", e);
response = new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
log.info("**********批量发送出参*******:{}", response);
return response;
}
/**
* 发送单条(通知或营销类)
*
* @return
*/
@RequestMapping("/sms/send")
public DmHubSendResponse send(@RequestBody DmHubSendRequest request) {
log.info("**********单条发送入参*******:{}", JSONObject.toJSONString(request));
DmHubSendResponse response;
try {
response = messageService.send(request);
} catch (Exception e) {
log.error("发送单条短信异常", e);
response = new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
log.info("**********单条发送出参*******:{}", JSONObject.toJSONString(response));
return response;
}
}
package com.bgy.sms.channel.bgy.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 短信参数配置
*/
@Component
public class BgySMSConfig {
// appId
public static String appId;
// 安全码
public static String securityCode;
// 请求地址
public static String url;
// 项目楼盘id
public static String areaId;
// api
public static String api;
@Value("${system.config.bgy.appId}")
public void setAppId(String appId) {
BgySMSConfig.appId = appId;
}
@Value("${system.config.bgy.securityCode}")
public void setSecurityCode(String securityCode) {
BgySMSConfig.securityCode = securityCode;
}
@Value("${system.config.bgy.url}")
public void setUrl(String url) {
BgySMSConfig.url = url;
}
@Value("${system.config.bgy.areaId}")
public void setAreaId(String areaId) {
BgySMSConfig.areaId = areaId;
}
@Value("${system.config.bgy.api}")
public void setApi(String api) {
BgySMSConfig.api = api;
}
}
package com.bgy.sms.channel.bgy.config;
/**
* 内容枚举类
*/
public enum ContentEnum {
SMS_TYPE_NOTIFICATION("notification", "通知类短信标识"),
SMS_TYPE_MARKETING("marketing", "营销类短信标识"),
SMS_STATUS_SUCCESS("DELIVRD", "创蓝短信发送状态--成功"),
SMS_STATUS_UNKNOWN("UNKNOWN", "创蓝短信发送状态--未知"),
SMS_STATUS_REFUSE("REJECTD", "创蓝短信发送状态--短信中心拒绝"),
SMS_STATUS_MBBLACK("MBBLACK", "创蓝短信发送状态--黑名单号码"),
SMS_STATUS_REJECT("REJECT", "创蓝短信发送状态--驳回");
private final String value;
private final String desc;
ContentEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return value;
}
public String getDesc() {
return desc;
}
}
package com.bgy.sms.channel.bgy.dto;
import com.alibaba.fastjson.JSONObject;
import com.bgy.sms.config.ResponseCode;
import java.io.Serializable;
public class CLBizResponse implements Serializable {
private static final long serialVersionUID = 8100192126279967648L;
private String code;
private String msg;
private String id;
private JSONObject data;
public CLBizResponse() {
}
public CLBizResponse(ResponseCode responseCode) {
this.code = responseCode.getCode();
this.msg = responseCode.getMsg();
}
public CLBizResponse(ResponseCode responseCode,JSONObject data) {
this.code = responseCode.getCode();
this.msg = responseCode.getMsg();
this.data = data;
}
public CLBizResponse(ResponseCode responseCode, String id) {
this.code = responseCode.getCode();
this.msg = responseCode.getMsg();
this.id = id;
}
public CLBizResponse(ResponseCode responseCode, String msg, int nullInfo) {
this.code = responseCode.getCode();
this.msg = responseCode.getMsg()+msg;
}
public CLBizResponse(String code, String msg) {
this.code = code;
this.msg = msg;
}
public CLBizResponse(String code, String msg, String id) {
this.code = code;
this.msg = msg;
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public JSONObject getData() {
return data;
}
public void setData(JSONObject data) {
this.data = data;
}
}
package com.bgy.sms.channel.bgy.dto;
import java.io.Serializable;
public class CLNotifyRequest implements Serializable {
private static final long serialVersionUID = 1L;
// 接口用户名
private String username;
// 十位时间戳
private String timestamp;
// 签名串
private String signature;
// 模块
private String action;
// 模板id
private String id;
// 审核状态(模板(1审核,2驳回),签名(2通过,3驳回))
private String auditStatus;
// 驳回原因
private String auditReason;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAuditStatus() {
return auditStatus;
}
public void setAuditStatus(String auditStatus) {
this.auditStatus = auditStatus;
}
public String getAuditReason() {
return auditReason;
}
public void setAuditReason(String auditReason) {
this.auditReason = auditReason;
}
}
package com.bgy.sms.channel.bgy.dto;
import java.io.Serializable;
public class CLSendFixedRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 创蓝API账号,必填
*/
private String account;
/**
* 创蓝API密码,必填
*/
private String password;
/**
* 短信内容。长度不能超过536个字符,必填
*/
private String msg;
/**
* 机号码。多个手机号码使用英文逗号分隔,必填
*/
private String phone;
/**
* 定时发送短信时间。格式为yyyyMMddHHmm,值小于或等于当前时间则立即发送,默认立即发送,选填
*/
private String sendtime;
/**
* 是否需要状态报告(默认false),选填
*/
private String report;
/**
* 下发短信号码扩展码,纯数字,建议1-3位,选填
*/
private String extend;
/**
* 该条短信在您业务系统内的ID,如订单号或者短信发送记录流水号,选填
*/
private String uid;
public CLSendFixedRequest() {
}
public CLSendFixedRequest(String account, String password, String msg, String phone) {
super();
this.account = account;
this.password = password;
this.msg = msg;
this.phone = phone;
}
public CLSendFixedRequest(String account, String password, String msg, String phone, String report) {
super();
this.account = account;
this.password = password;
this.msg = msg;
this.phone = phone;
this.report = report;
}
public CLSendFixedRequest(String account, String password, String msg, String phone, String report, String uid) {
super();
this.account = account;
this.password = password;
this.msg = msg;
this.phone = phone;
this.report = report;
this.uid = uid;
}
public CLSendFixedRequest(String account, String password, String msg, String phone, String sendtime, String report, String uid) {
super();
this.account = account;
this.password = password;
this.msg = msg;
this.phone = phone;
this.sendtime = sendtime;
this.report = report;
this.uid = uid;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSendtime() {
return sendtime;
}
public void setSendtime(String sendtime) {
this.sendtime = sendtime;
}
public String getReport() {
return report;
}
public void setReport(String report) {
this.report = report;
}
public String getExtend() {
return extend;
}
public void setExtend(String extend) {
this.extend = extend;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
}
package com.bgy.sms.channel.bgy.dto;
import java.io.Serializable;
public class CLSendSMSResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 响应时间
*/
private String time;
/**
* 消息id
*/
private String msgId;
/**
* 状态码说明(成功返回空)
*/
private String errorMsg;
/**
* 状态码(详细参考提交响应状态码)
*/
private String code;
private String failNum;
private String successNum;
public CLSendSMSResponse() {
}
public CLSendSMSResponse(String code, String errorMsg) {
this.code = code;
this.errorMsg = errorMsg;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getFailNum() {
return failNum;
}
public void setFailNum(String failNum) {
this.failNum = failNum;
}
public String getSuccessNum() {
return successNum;
}
public void setSuccessNum(String successNum) {
this.successNum = successNum;
}
@Override
public String toString() {
return "SmsSingleResponse [time=" + time + ", msgId=" + msgId + ", errorMsg=" + errorMsg + ", code=" + code
+ "]";
}
}
package com.bgy.sms.channel.bgy.dto;
import java.io.Serializable;
public class CLSendVariableRequest implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 创蓝API账号,必填
*/
private String account;
/**
* 创蓝API密码,必填
*/
private String password;
/**
* 短信内容。长度不能超过536个字符,必填
*/
private String msg;
/**
* 手机号码和变量参数,多组参数使用英文分号;区分,必填
*/
private String params;
/**
* 定时发送短信时间。格式为yyyyMMddHHmm,值小于或等于当前时间则立即发送,默认立即发送,选填
*/
private String sendtime;
/**
* 是否需要状态报告(默认false),选填
*/
private String report;
/**
* 下发短信号码扩展码,纯数字,建议1-3位,选填
*/
private String extend;
/**
* 该条短信在您业务系统内的ID,如订单号或者短信发送记录流水号,选填
*/
private String uid;
public CLSendVariableRequest() {
}
public CLSendVariableRequest(String account, String password, String msg, String params) {
super();
this.account = account;
this.password = password;
this.msg = msg;
this.params = params;
}
public CLSendVariableRequest(String account, String password, String msg, String params, String report) {
super();
this.account = account;
this.password = password;
this.msg = msg;
this.params = params;
this.report = report;
}
public CLSendVariableRequest(String account, String password, String msg, String params, String report,String uid) {
super();
this.account = account;
this.password = password;
this.msg = msg;
this.params = params;
this.report = report;
this.uid = uid;
}
// public SmsVarableRequest(String account, String password, String msg, String params, String sendtime) {
// super();
// this.account = account;
// this.password = password;
// this.msg = msg;
// this.params = params;
// this.sendtime = sendtime;
// }
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getSendtime() {
return sendtime;
}
public void setSendtime(String sendtime) {
this.sendtime = sendtime;
}
public String getReport() {
return report;
}
public void setReport(String report) {
this.report = report;
}
public String getExtend() {
return extend;
}
public void setExtend(String extend) {
this.extend = extend;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
}
package com.bgy.sms.channel.bgy.dto;
import java.io.Serializable;
public class CLSendVariableResponse implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 响应时间
*/
private String time;
/**
* 消息id
*/
private String msgId;
/**
* 状态码说明(成功返回空)
*/
private String errorMsg;
/**
* 失败的个数
*/
private String failNum;
/**
* 成功的个数
*/
private String successNum;
/**
* 状态码(详细参考提交响应状态码)
*/
private String code;
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getFailNum() {
return failNum;
}
public void setFailNum(String failNum) {
this.failNum = failNum;
}
public String getSuccessNum() {
return successNum;
}
public void setSuccessNum(String successNum) {
this.successNum = successNum;
}
@Override
public String toString() {
return "SmsVarableResponse [time=" + time + ", msgId=" + msgId + ", errorMsg=" + errorMsg + ", failNum="
+ failNum + ", successNum=" + successNum + ", code=" + code + "]";
}
}
package com.bgy.sms.channel.bgy.dto;
public class CLTemplateRequest {
}
package com.bgy.sms.channel.bgy.dto;
import java.io.Serializable;
public class ReportDto implements Serializable {
private static final long serialVersionUID = 1L;
private String receiver;
private String pswd;
private String msgid;
private String reportTime;
private String mobile;
private String notifyTime;
private String uid;
private String length;
private String status;
private String statusDesc;
public String getReceiver() {
return receiver;
}
public void setReceiver(String receiver) {
this.receiver = receiver;
}
public String getPswd() {
return pswd;
}
public void setPswd(String pswd) {
this.pswd = pswd;
}
public String getMsgid() {
return msgid;
}
public void setMsgid(String msgid) {
this.msgid = msgid;
}
public String getReportTime() {
return reportTime;
}
public void setReportTime(String reportTime) {
this.reportTime = reportTime;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getNotifyTime() {
return notifyTime;
}
public void setNotifyTime(String notifyTime) {
this.notifyTime = notifyTime;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getLength() {
return length;
}
public void setLength(String length) {
this.length = length;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatusDesc() {
return statusDesc;
}
public void setStatusDesc(String statusDesc) {
this.statusDesc = statusDesc;
}
@Override
public String toString() {
return "ReportDto{" +
"receiver='" + receiver + '\'' +
", pswd='" + pswd + '\'' +
", msgid='" + msgid + '\'' +
", reportTime='" + reportTime + '\'' +
", mobile='" + mobile + '\'' +
", notifyTime='" + notifyTime + '\'' +
", uid='" + uid + '\'' +
", length='" + length + '\'' +
", status='" + status + '\'' +
", statusDesc='" + statusDesc + '\'' +
'}';
}
}
package com.bgy.sms.channel.bgy.service;
import com.bgy.sms.channel.bgy.dto.CLBizResponse;
public interface BgySmsService {
CLBizResponse sendSms(String mobile, String content) throws Exception;
}
package com.bgy.sms.channel.bgy.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.bgy.sms.channel.bgy.config.BgySMSConfig;
import com.bgy.sms.channel.bgy.dto.CLBizResponse;
import com.bgy.sms.channel.bgy.service.BgySmsService;
import com.bgy.sms.channel.bgy.utils.SendSmsUtil;
import com.bgy.sms.channel.dmHub.service.DmHubService;
import com.bgy.sms.config.ResponseCode;
import com.bgy.sms.service.SmsTemplateService;
import com.bgy.util.Md5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("DuplicatedCode")
@Service
public class BgySmsServiceImpl implements BgySmsService {
private static final Logger log = LoggerFactory.getLogger(BgySmsServiceImpl.class);
private static final String SUCCESS = "success";
private static final String sendSuccessCode = "0"; // 发送响应成功字段
private static final String createTemplateStatus = "status"; // 响应状态字段
private static final String retMsg = "msg"; // 响应描述
private static final String createTemplateData = "data"; // 创建模板响应数据
private static final String notificationId = "49"; // 创蓝通知类短信ID
private static final String marketingId = "52"; // 创蓝营销类短信ID
@Autowired
private SmsTemplateService templateService;
@Autowired
private DmHubService dmHubService;
@Override
public CLBizResponse sendSms(String mobile, String content) throws Exception {
String appId = BgySMSConfig.appId;
String securityCode = BgySMSConfig.securityCode;
String url = BgySMSConfig.url;
String areaId = BgySMSConfig.areaId;
String api = BgySMSConfig.api;
Map<String, String> requestParams = new HashMap<>();
requestParams.put("api", api);
requestParams.put("appId", appId);
requestParams.put("security", Md5Util.encrypt(appId + securityCode.toUpperCase()));
requestParams.put("areaId", areaId);
requestParams.put("content", content);
requestParams.put("mobile", mobile);
String retStr = SendSmsUtil.sendSmsByPost(url, JSONObject.toJSONString(requestParams));
if (retStr == null) {
return new CLBizResponse(ResponseCode.UPSTREAM_BLANK);
}
JSONObject retJson = JSONObject.parseObject(retStr);
String err = retJson.getString("err");
String retPack = retJson.getString("package");
String retCode = retJson.getString("ret");
if (!sendSuccessCode.equals(retCode)) {
return new CLBizResponse(ResponseCode.UPSTREAM_FAIL.getCode(), err);
} else {
return new CLBizResponse(ResponseCode.SUCCESS);
}
}
}
package com.bgy.sms.channel.bgy.utils;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
//import java.io.PrintWriter;
/**
* @author tianyh
* @Description:HTTP 请求
*/
@SuppressWarnings("Duplicates")
public class SendSmsUtil {
/**
* @param path
* @param postContent
* @return String
* @throws
* @author tianyh
* @Description
*/
public static String sendSmsByPost(String path, String postContent) {
URL url = null;
try {
url = new URL(path);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");// 提交模式
httpURLConnection.setConnectTimeout(10000);//连接超时 单位毫秒
httpURLConnection.setReadTimeout(10000);//读取超时 单位毫秒
// 发送POST请求必须设置如下两行
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestProperty("Charset", "UTF-8");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
// PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// printWriter.write(postContent);
// printWriter.flush();
httpURLConnection.connect();
OutputStream os = httpURLConnection.getOutputStream();
os.write(postContent.getBytes("UTF-8"));
os.flush();
StringBuilder sb = new StringBuilder();
int httpRspCode = httpURLConnection.getResponseCode();
if (httpRspCode == HttpURLConnection.HTTP_OK) {
// 开始获取数据
BufferedReader br = new BufferedReader(
new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
return sb.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String sendTemplateByPost(String path, String postContent) {
URL url = null;
try {
url = new URL(path);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");// 提交模式
httpURLConnection.setConnectTimeout(10000);//连接超时 单位毫秒
httpURLConnection.setReadTimeout(10000);//读取超时 单位毫秒
// 发送POST请求必须设置如下两行
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestProperty("Charset", "UTF-8");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
// PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// printWriter.write(postContent);
// printWriter.flush();
httpURLConnection.connect();
OutputStream os = httpURLConnection.getOutputStream();
os.write(postContent.getBytes("UTF-8"));
os.flush();
StringBuilder sb = new StringBuilder();
int httpRspCode = httpURLConnection.getResponseCode();
if (httpRspCode == HttpURLConnection.HTTP_OK) {
// 开始获取数据
BufferedReader br = new BufferedReader(
new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
return sb.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.bgy.sms.channel.dmHub.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class DmHubConfig {
// 应用过id
public static String applicationId;
// 应用key
public static String applicationKey;
public static String tokenUrl;
public static String report;
@Value("${system.config.dmHub.applicationId}")
public void setApplicationId(String applicationId) {
DmHubConfig.applicationId = applicationId;
}
@Value("{system.config.dmHub.applicationKey}")
public void setApplicationKey(String applicationKey) {
DmHubConfig.applicationKey = applicationKey;
}
@Value("{system.config.dmHub.tokenUrl}")
public void setTokenUrl(String tokenUrl) {
DmHubConfig.tokenUrl = tokenUrl;
}
@Value("{system.config.dmHub.report}")
public void setReport(String report) {
DmHubConfig.report = report;
}
}
package com.bgy.sms.channel.dmHub.service;
import com.bgy.sms.channel.bgy.dto.ReportDto;
import java.util.Map;
public interface DmHubService {
/**
* 获取DM hub token,用户请求DM hub接口
*
* @return token信息
*/
String getToken() ;
/**
* 回执报告给DM hub
*
* @param dto
* @return
*/
Map<String, Object> smsReport(ReportDto dto) throws Exception;
}
package com.bgy.sms.channel.dmHub.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.bgy.sms.channel.bgy.config.ContentEnum;
import com.bgy.sms.channel.bgy.dto.ReportDto;
import com.bgy.sms.channel.dmHub.config.DmHubConfig;
import com.bgy.sms.channel.dmHub.service.DmHubService;
import com.bgy.sms.channel.dto.DmhubReport;
import com.bgy.sms.channel.dto.ReportDetail;
import com.bgy.util.HttpUtil;
import com.bgy.util.OkHttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Dm hub系统交互业务层
*/
@Service
public class DmHubServiceImpl implements DmHubService {
private static final Logger log = LoggerFactory.getLogger(DmHubServiceImpl.class);
private static final String TOKEN_KEY = "DM_HUB_API_TOKEN";
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public String getToken() {
try {
Long expire = redisTemplate.getExpire(TOKEN_KEY, TimeUnit.SECONDS);
Object token = redisTemplate.opsForValue().get(TOKEN_KEY);
if (expire != null && expire > 0L && token != null) {
return token.toString();
} else {
String appid = DmHubConfig.applicationId;
String secret = DmHubConfig.applicationKey;
String tokenUrl = DmHubConfig.tokenUrl;
String grantType = "client_credentials";
Map<String, String> requestMap = new HashMap<>();
requestMap.put("appid", appid);
requestMap.put("secret", secret);
requestMap.put("grant_type", grantType);
String retStr = OkHttpUtil.get(tokenUrl, requestMap);
JSONObject retJson = JSONObject.parseObject(retStr);
String errorCode = retJson.getString("error_code");
if ("0".equals(errorCode)) {
String accessToken = retJson.getString("access_token");
String expires = retJson.getString("expires_in");
long exTime = Long.parseLong(expires) - 60 * 10L;
redisTemplate.opsForValue().set(TOKEN_KEY, accessToken, exTime, TimeUnit.SECONDS);
return accessToken;
} else {
// TODO 系统告警,获取API接口TOKEN失败。
return null;
}
}
} catch (Exception e) {
log.error("获取API接口TOKEN业务逻辑异常,异常信息:\r\n", e);
return null;
}
}
@Override
public Map<String, Object> smsReport(ReportDto dto) throws Exception {
try {
String token = getToken();
if (StringUtils.isBlank(token)) {
return null;
}
String uidStr = dto.getUid();
JSONObject uidJson = JSONObject.parseObject(uidStr);
String dmHubBatchId = uidJson.getString("dmHubId");
String sysBatchId = uidJson.getString("sysBatchId");
DmhubReport report = new DmhubReport();
report.setAccess_token(token);
report.setType("sms");
ReportDetail detail = new ReportDetail();
detail.setAudienceId(dto.getMobile());
detail.setBatchId(dmHubBatchId);
detail.setReportDate(dto.getReportTime());
detail.setMobile(dto.getMobile());
detail.setChargeNum(Integer.valueOf(dto.getLength()));
detail.setSendDate(dto.getReportTime());
if (ContentEnum.SMS_STATUS_SUCCESS.getValue().equals(dto.getStatus())) {
detail.setIsReceive(true);
} else {
detail.setIsReceive(false);
}
detail.setErrMessage(dto.getStatusDesc());
report.setReports(detail);
log.info("短信状态回执参数:{}", JSONObject.toJSONString(report));
String retStr = HttpUtil.sendPost(DmHubConfig.report, JSONObject.toJSONString(report));
log.info("短信状态回执响应:{}", retStr);
//TODO 目前没有测试环境的请求地址
} catch (Exception e) {
log.info("发送短信回执到DMHub异常\r\n短信信息:{},\r\n,异常:", dto, e);
}
return null;
}
}
package com.bgy.sms.channel.dto;
import com.alibaba.fastjson.JSONObject;
import java.io.Serializable;
import java.util.List;
public class DmHubBatchSendRequest implements Serializable {
private static final long serialVersionUID = 1L;
// 批量发送短信的模板id
private String templateId;
// 批次号
private String batchId;
// 账号类型(mobile就传手机号)
private String audienceIdType;
// 短信数据
private List<JSONObject> data;
public String getTemplateId() {
return templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public String getBatchId() {
return batchId;
}
public void setBatchId(String batchId) {
this.batchId = batchId;
}
public List<JSONObject> getData() {
return data;
}
public void setData(List<JSONObject> data) {
this.data = data;
}
public String getAudienceIdType() {
return audienceIdType;
}
public void setAudienceIdType(String audienceIdType) {
this.audienceIdType = audienceIdType;
}
}
package com.bgy.sms.channel.dto;
import com.alibaba.fastjson.JSONObject;
import java.io.Serializable;
public class DmHubSendRequest implements Serializable {
private static final long serialVersionUID = 1L;
// 发送短信的模板ID
private String templateId;
// DMHUb的批次号
private String batchId;
// 渠道类型(初期给到DMHUb系统库的类型,如果是sms,data里面会直接反手机号,
// 如果是customerIdentity.memberId,data返回memberId,需要查询系统memberId用户对应的手机号发送短信)
private String audienceIdType;
// 发送数据
private JSONObject data;
public String getTemplateId() {
return templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public String getBatchId() {
return batchId;
}
public void setBatchId(String batchId) {
this.batchId = batchId;
}
public String getAudienceIdType() {
return audienceIdType;
}
public void setAudienceIdType(String audienceIdType) {
this.audienceIdType = audienceIdType;
}
public JSONObject getData() {
return data;
}
public void setData(JSONObject data) {
this.data = data;
}
}
package com.bgy.sms.channel.dto;
import com.bgy.sms.config.ResponseCode;
import java.io.Serializable;
public class DmHubSendResponse implements Serializable {
private static final long serialVersionUID = 1L;
private String code;
private String msg;
public DmHubSendResponse() {
}
public DmHubSendResponse(String code, String msg) {
this.code = code;
this.msg = msg;
}
public DmHubSendResponse(ResponseCode responseCode) {
this.code = responseCode.getCode();
this.msg = responseCode.getMsg();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "DmHubSendResponse{" +
"code='" + code + '\'' +
", msg='" + msg + '\'' +
'}';
}
}
package com.bgy.sms.channel.dto;
import java.io.Serializable;
public class DmHubTemplateRequest implements Serializable {
private static final long serialVersionUID = 1L;
private String tenantId;
private String templateId;
private String templateContent;
private String smsType;
private String signature;
private String templateName;
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getTemplateId() {
return templateId;
}
public void setTemplateId(String templateId) {
this.templateId = templateId;
}
public String getTemplateContent() {
return templateContent;
}
public void setTemplateContent(String templateContent) {
this.templateContent = templateContent;
}
public String getSmsType() {
return smsType;
}
public void setSmsType(String smsType) {
this.smsType = smsType;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getTemplateName() {
return templateName;
}
public void setTemplateName(String templateName) {
this.templateName = templateName;
}
}
package com.bgy.sms.channel.dto;
import com.bgy.sms.config.ResponseCode;
import java.io.Serializable;
public class DmHubTemplateResponse implements Serializable {
private static final long serialVersionUID = 1L;
private String code;
private String msg;
public DmHubTemplateResponse() {
}
public DmHubTemplateResponse(String code, String msg) {
this.code = code;
this.msg = msg;
}
public DmHubTemplateResponse(ResponseCode responseCode) {
this.code = responseCode.getCode();
this.msg = responseCode.getMsg();
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
package com.bgy.sms.channel.dto;
import java.io.Serializable;
public class DmhubReport implements Serializable {
private static final long serialVersionUID = 810019212627996764L;
private String type;
private String access_token;
private ReportDetail reports;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public ReportDetail getReports() {
return reports;
}
public void setReports(ReportDetail reports) {
this.reports = reports;
}
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
}
package com.bgy.sms.channel.dto;
import java.io.Serializable;
public class ReportDetail implements Serializable {
private static final long serialVersionUID = 810019212627996764L;
private String audienceId;
private String batchId;
private String reportDate;
private Boolean isReceive;
private String mobile;
private Integer chargeNum;
private String sendDate;
private String errMessage;
private String content;
private String msgCode;
private String campaign;
public String getAudienceId() {
return audienceId;
}
public void setAudienceId(String audienceId) {
this.audienceId = audienceId;
}
public String getBatchId() {
return batchId;
}
public void setBatchId(String batchId) {
this.batchId = batchId;
}
public String getReportDate() {
return reportDate;
}
public void setReportDate(String reportDate) {
this.reportDate = reportDate;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getSendDate() {
return sendDate;
}
public void setSendDate(String sendDate) {
this.sendDate = sendDate;
}
public String getErrMessage() {
return errMessage;
}
public void setErrMessage(String errMessage) {
this.errMessage = errMessage;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMsgCode() {
return msgCode;
}
public void setMsgCode(String msgCode) {
this.msgCode = msgCode;
}
public String getCampaign() {
return campaign;
}
public void setCampaign(String campaign) {
this.campaign = campaign;
}
public Boolean getIsReceive() {
return isReceive;
}
public void setIsReceive(Boolean receive) {
isReceive = receive;
}
public Integer getChargeNum() {
return chargeNum;
}
public void setChargeNum(Integer chargeNum) {
this.chargeNum = chargeNum;
}
}
package com.bgy.sms.config;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
//@MapperScan("com.baomidou.springboot.mapper*")//这个注解,作用相当于下面的@Bean MapperScannerConfigurer,2者配置1份即可
public class MybatisPlusConfig {
/**
* SQL输出拦截器,性能分析器,不建议生产环境使用,开发环境使用(方便)
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
//sql格式化
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
/**
* mybatis-plus分页插件<br>
* 文档:http://mp.baomidou.com<br>
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
//paginationInterceptor.setDialectType("mysql"); //指定数据库类型,不写自动匹配
return paginationInterceptor;
};
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();
scannerConfigurer.setBasePackage("com.baomidou.springboot.mapper*");
return scannerConfigurer;
}
}
\ No newline at end of file
package com.bgy.sms.config;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class OkHttpConfig {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient().newBuilder().retryOnConnectionFailure(false).connectionPool(pool())
.connectTimeout(5, TimeUnit.SECONDS).readTimeout(5, TimeUnit.SECONDS).writeTimeout(5, TimeUnit.SECONDS)
.build();
}
@Bean
public ConnectionPool pool() {
return new ConnectionPool(50, 5, TimeUnit.MINUTES);
}
}
package com.bgy.sms.config;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig{
@Bean
public RedisTemplate<String, Object> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//全局开启
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
//key序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//value序列化
redisTemplate.setValueSerializer(new FastJsonRedisSerializer<>(Object.class));
redisTemplate.setHashValueSerializer(new FastJsonRedisSerializer<>(Object.class));
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
package com.bgy.sms.config;
public enum ResponseCode {
// 系统判断错误
SUCCESS("200", "处理成功"),
UNKNOWN_TEMPLATE_TYPE("500", "未知模板类型"),
TEMPLATE_ALREADY_EXISTED("500", "DM Hub模板ID冲突"),
SYSTEM_ERROR("99", "系统异常:"),
// 渠道异常错误
UPSTREAM_FAIL("US01", "渠道交易失败"),
UPSTREAM_UNKNOWN_MODEL("US01", "未知通知模式"),
UPSTREAM_BLANK("US00", "渠道同步响应为空");
private String code;
private String msg;
ResponseCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
package com.bgy.sms.repository.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serializable;
import java.util.Date;
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 8100192126279967648L;
// 表关键字
protected Long id;
// 记录是否逻辑删除(默认为false)
private Boolean delFlag = false;
// 记录创建人信息
private String creater;
// 记录创建日期
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
// 记录更新人信息
private String updater;
// 记录最近修改日期
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
//获取redis的key值
private String key;
}
package com.bgy.sms.repository.domain;
import com.baomidou.mybatisplus.annotations.TableName;
import java.util.Date;
@TableName("dm_batch")
public class DmBatchInfo {
private Long id;
private String dmBatchId;
private String dmTemplateId;
private Integer smsNum;
private Integer successNum;
private Integer failNum;
private Date dateCreated;
private Date lastUpdated;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDmBatchId() {
return dmBatchId;
}
public void setDmBatchId(String dmBatchId) {
this.dmBatchId = dmBatchId;
}
public String getDmTemplateId() {
return dmTemplateId;
}
public void setDmTemplateId(String dmTemplateId) {
this.dmTemplateId = dmTemplateId;
}
public Integer getSmsNum() {
return smsNum;
}
public void setSmsNum(Integer smsNum) {
this.smsNum = smsNum;
}
public Integer getSuccessNum() {
return successNum;
}
public void setSuccessNum(Integer successNum) {
this.successNum = successNum;
}
public Integer getFailNum() {
return failNum;
}
public void setFailNum(Integer failNum) {
this.failNum = failNum;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
}
package com.bgy.sms.repository.domain;
import com.baomidou.mybatisplus.annotations.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
@TableName("sms_template")
public class SmsTemplateInfo {
private Long id;
private String dmTemplateId;
private String type;
private String status;
// DM 模板内容
private String content;
// 上游模板内容
private String upContent;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date dateCreated;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastUpdated;
private String signature;
private String tenantId;
private String templateName;
private String upTemplateId;
private String upRejectMsg;
private String params;
public SmsTemplateInfo() {
}
public String getUpContent() {
return upContent;
}
public void setUpContent(String upContent) {
this.upContent = upContent;
}
public String getTemplateName() {
return templateName;
}
public void setTemplateName(String templateName) {
this.templateName = templateName;
}
public SmsTemplateInfo(String dmTemplateId) {
this.dmTemplateId = dmTemplateId;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDmTemplateId() {
return dmTemplateId;
}
public void setDmTemplateId(String dmTemplateId) {
this.dmTemplateId = dmTemplateId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
public String getUpTemplateId() {
return upTemplateId;
}
public void setUpTemplateId(String upTemplateId) {
this.upTemplateId = upTemplateId;
}
public String getUpRejectMsg() {
return upRejectMsg;
}
public void setUpRejectMsg(String upRejectMsg) {
this.upRejectMsg = upRejectMsg;
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
}
package com.bgy.sms.repository.domain;
import com.baomidou.mybatisplus.annotations.TableName;
import java.util.Date;
@TableName("sys_batch")
public class SysBatchInfo {
private Long id;
private String dmBatchId;
private String dmTemplateId;
private Long batchId;
private String report;
private Integer smsNum;
private String extend;
private String msgId;
private String errorMsg;
private String code;
private Date dateCreated;
private Date lastUpdated;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDmBatchId() {
return dmBatchId;
}
public void setDmBatchId(String dmBatchId) {
this.dmBatchId = dmBatchId;
}
public String getDmTemplateId() {
return dmTemplateId;
}
public void setDmTemplateId(String dmTemplateId) {
this.dmTemplateId = dmTemplateId;
}
public Long getBatchId() {
return batchId;
}
public void setBatchId(Long batchId) {
this.batchId = batchId;
}
public String getReport() {
return report;
}
public void setReport(String report) {
this.report = report;
}
public String getExtend() {
return extend;
}
public void setExtend(String extend) {
this.extend = extend;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Date getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(Date lastUpdated) {
this.lastUpdated = lastUpdated;
}
public Integer getSmsNum() {
return smsNum;
}
public void setSmsNum(Integer smsNum) {
this.smsNum = smsNum;
}
}
package com.bgy.sms.repository.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.bgy.sms.repository.domain.DmBatchInfo;
public interface DmBatchMapper extends BaseMapper<DmBatchInfo> {
}
package com.bgy.sms.repository.mapper;
/**
* Mybatis 接口文件
*/
public interface MessageMapper {
// int createTemplate(XXXX....)
}
package com.bgy.sms.repository.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.bgy.sms.repository.domain.SysBatchInfo;
public interface SysBatchMapper extends BaseMapper<SysBatchInfo> {
}
package com.bgy.sms.repository.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.bgy.sms.repository.domain.SmsTemplateInfo;
public interface TemplateMapper extends BaseMapper<SmsTemplateInfo> {
}
package com.bgy.sms.service;
import com.baomidou.mybatisplus.service.IService;
import com.bgy.sms.repository.domain.DmBatchInfo;
public interface DmBatchService extends IService<DmBatchInfo> {
}
package com.bgy.sms.service;
import com.bgy.sms.channel.dto.*;
public interface MessageService {
/**
* DM hub创建模板同步插件接口
*
* @param requestDTO
* @return
*/
DmHubTemplateResponse createTemplate(DmHubTemplateRequest requestDTO);
/**
* DM hub发送短信接口
*
* @param requestDTO
* @return
*/
DmHubSendResponse send(DmHubSendRequest requestDTO);
/**
* DM hub批量发送短信接口
*
* @param requestDTO
* @return
*/
DmHubSendResponse batchSend(DmHubBatchSendRequest requestDTO);
/**
* DM hub批量发送短信接口
*
* @param requestDTO
* @return
*/
DmHubSendResponse batchSendOneByOne(DmHubBatchSendRequest requestDTO);
}
package com.bgy.sms.service;
import com.baomidou.mybatisplus.service.IService;
import com.bgy.sms.repository.domain.SmsTemplateInfo;
public interface SmsTemplateService extends IService<SmsTemplateInfo> {
}
package com.bgy.sms.service;
import com.baomidou.mybatisplus.service.IService;
import com.bgy.sms.repository.domain.SysBatchInfo;
public interface SysBatchService extends IService<SysBatchInfo> {
}
package com.bgy.sms.service.bean;
import com.alibaba.fastjson.JSONArray;
public class TemplateChangeBean {
// 创蓝发送短信时需要用的模板内容
private String upSendStr;
// 创蓝创建短信模板需要的模板内容
private String upCreateStr;
private JSONArray params;
public TemplateChangeBean() {
}
public TemplateChangeBean(String upSendStr, JSONArray params, String upCreateStr) {
this.upSendStr = upSendStr;
this.params = params;
this.upCreateStr = upCreateStr;
}
public String getUpSendStr() {
return upSendStr;
}
public void setUpSendStr(String upSendStr) {
this.upSendStr = upSendStr;
}
public String getUpCreateStr() {
return upCreateStr;
}
public void setUpCreateStr(String upCreateStr) {
this.upCreateStr = upCreateStr;
}
public JSONArray getParams() {
return params;
}
public void setParams(JSONArray params) {
this.params = params;
}
}
package com.bgy.sms.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.bgy.sms.repository.domain.DmBatchInfo;
import com.bgy.sms.repository.mapper.DmBatchMapper;
import com.bgy.sms.service.DmBatchService;
import org.springframework.stereotype.Service;
@Service
public class DmBatchServiceImpl extends ServiceImpl<DmBatchMapper, DmBatchInfo> implements DmBatchService {
}
package com.bgy.sms.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.bgy.sms.channel.bgy.dto.CLBizResponse;
import com.bgy.sms.channel.bgy.service.BgySmsService;
import com.bgy.sms.config.ResponseCode;
import com.bgy.sms.channel.dto.*;
import com.bgy.sms.repository.domain.DmBatchInfo;
import com.bgy.sms.repository.domain.SmsTemplateInfo;
import com.bgy.sms.repository.domain.SysBatchInfo;
import com.bgy.sms.service.DmBatchService;
import com.bgy.sms.service.MessageService;
import com.bgy.sms.service.SmsTemplateService;
import com.bgy.sms.service.bean.TemplateChangeBean;
import com.bgy.util.id.IdHandler;
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.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings("Duplicates")
@Service
public class MessageServiceImpl implements MessageService {
private static final Logger log = LoggerFactory.getLogger(MessageServiceImpl.class);
@Autowired
private SysBatchServiceImpl sysBatchService;
@Autowired
private SmsTemplateService smsTemplateService;
@Autowired
private BgySmsService bgySmsService;
@Autowired
private DmBatchService dmBatchService;
/**
* 短信模板创建
*
* @param requestDTO
* @return
*/
@Override
public DmHubTemplateResponse createTemplate(DmHubTemplateRequest requestDTO) {
log.info("进入创建短信模板业务逻辑,入参:{}", requestDTO);
DmHubTemplateResponse responseDTO = new DmHubTemplateResponse(ResponseCode.SUCCESS);
try {
String templateContent = requestDTO.getTemplateContent();
String signature = requestDTO.getSignature();
String smsType = requestDTO.getSmsType();
String tenantId = requestDTO.getTenantId();
String templateId = requestDTO.getTemplateId();
String templateName = requestDTO.getTemplateName();
// 替换模板格式,保存适合创蓝发送短信的模板,避免发送时修改模板格式
TemplateChangeBean bean = dmHub2BgyTemplateSend(templateContent);
String chuanglanSend = bean.getUpSendStr();
String params = bean.getParams().toString();
SmsTemplateInfo dbInfo = smsTemplateService.selectOne(new EntityWrapper<SmsTemplateInfo>().eq("dm_template_id", templateId));
if (dbInfo != null) {
log.error("Dm Hub请求创建模板,模板id已存在,模板id:【{}】", templateId);
return new DmHubTemplateResponse(ResponseCode.TEMPLATE_ALREADY_EXISTED);
}
SmsTemplateInfo info = new SmsTemplateInfo();
info.setContent(templateContent);
info.setType(smsType);
info.setDmTemplateId(templateId);
info.setTenantId(tenantId);
info.setId(IdHandler.nextId());
info.setSignature(signature);
info.setTemplateName(templateName);
info.setDateCreated(new Date());
info.setLastUpdated(new Date());
info.setLastUpdated(new Date());
info.setUpContent(chuanglanSend);
info.setParams(params);
boolean insert = smsTemplateService.insert(info);
if (!insert) {
//TODO 发送告警
log.error("模板插入DB异常:【{}】", JSONObject.toJSONString(info));
return new DmHubTemplateResponse(ResponseCode.SYSTEM_ERROR);
}
} catch (Exception exception) {
log.error("创建模板业务逻辑异常,错误信息", exception);
responseDTO = new DmHubTemplateResponse(ResponseCode.SYSTEM_ERROR);
}
return responseDTO;
}
/**
* 将DM HUb的模板装成可以简单模式模板,用户后续参数封装
*
* @param content
* @return
*/
private TemplateChangeBean dmHub2BgyTemplateSend(String content) {
//正则获取${***} 和 ${surl***'}格式的内容,其中:((?:\$\{surl.*'\}))獲取${surl***'}格式,\$\{[^}]+\} 获取${***}格式,顺序不能变,否则不能完成匹配格式一
String regex = "((?:\\$\\{surl.*'\\}))|\\$\\{[^}]+\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(content);
List<String> groups = new ArrayList<>();
while (matcher.find()) {
String group = matcher.group();
groups.add(group);
}
JSONArray arr = new JSONArray();
if (groups.isEmpty()) {
return new TemplateChangeBean(content, arr, content);
}
String upCreateStr = content;
String upSendStr = content;
for (String g : groups) {
String t = g;
g = Matcher.quoteReplacement(g);
g = escapeRegex(g);
upSendStr = upSendStr.replaceAll(g, "\\{\\$var\\}");
if (t.contains("${surl!")) {
// 短链没传长度,固定长度20
upCreateStr = upCreateStr.replaceAll(g, "\\{s20\\}");
} else {
int i = t.indexOf("@");
int i1 = t.indexOf("!");
String str = t.substring(i + 1, i1);
if (isNumeric(str)) {
Integer integer = Integer.valueOf(str);
if (integer == 0) {
upCreateStr = upCreateStr.replaceAll(g, "\\{s20\\}");
} else {
upCreateStr = upCreateStr.replaceAll(g, "\\{s" + integer + "\\}");
}
} else {
upCreateStr = upCreateStr.replaceAll(g, "\\{s20\\}");
}
}
}
arr.addAll(groups);
return new TemplateChangeBean(upSendStr, arr, upCreateStr);
}
private boolean isNumeric(String str) {
if (StringUtils.isBlank(str)) {
return false;
}
for (int i = 0; i < str.length(); i++) {
System.out.println(str.charAt(i));
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
private static String escapeRegex(String s) {
String[] symbols = new String[]{"\\/", "\\[", "\\]", "\\(", "\\)", "\\{", "\\}", "\\?", "\\+", "\\*", "\\|", "\\.", "\\^", "\\-", "\\^"};
if (s != null) {
for (String sym : symbols) {
s = s.replaceAll(sym, "\\" + sym);
}
}
return s;
}
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public DmHubSendResponse send(DmHubSendRequest requestDTO) {
try {
String dmHubBatchId = requestDTO.getBatchId();
String templateId = requestDTO.getTemplateId();
String audienceIdType = requestDTO.getAudienceIdType();
JSONObject data = requestDTO.getData();
// 1、获取模板信息
SmsTemplateInfo templateInfo = smsTemplateService.selectOne(new EntityWrapper<SmsTemplateInfo>().eq("dm_template_id", templateId));
if (null == templateInfo) {
return null;
}
// 2、根据请求信息获取用户的手机号码(此处不考虑配置DMHUB系统不是SMS的情况),直接拿请求体中的_audienceId字段值,该值为手机号码
// 模板参数占位符
String params = templateInfo.getParams();
JSONArray paramsArr = JSONArray.parseArray(params);
// 封装参数
List<String> paramList = new ArrayList<>();
Set<String> keys = data.keySet();
String mobile = data.getString("_audienceId");
data.remove("name");
data.remove("id");
data.remove("_audienceId");
if (!data.isEmpty()) {
for (Object parm : paramsArr) {
String s = parm.toString();
for (String key : keys) {
String newKey = key;
Object value = data.get(key);
if (value instanceof JSONObject || value instanceof Map) {
StringBuilder keyBuffer = new StringBuilder(key);
value = getKeyValue(value, keyBuffer);
newKey = keyBuffer.toString();
}
if (s.contains(newKey)) {
paramList.add(value.toString());
}
}
}
} else {
return null;
}
String type = templateInfo.getType();
// 3、记录批次信息
SysBatchInfo sysBatchInfo = new SysBatchInfo();
long sysBatchId = IdHandler.nextId();
sysBatchInfo.setBatchId(sysBatchId);
sysBatchInfo.setDmBatchId(dmHubBatchId);
sysBatchInfo.setId(IdHandler.nextId());
sysBatchInfo.setDmTemplateId(templateId);
sysBatchInfo.setReport("1");
sysBatchInfo.setSmsNum(1);
sysBatchInfo.setDateCreated(new Date());
sysBatchInfo.setLastUpdated(new Date());
boolean insert = sysBatchService.insert(sysBatchInfo);
CLBizResponse response = new CLBizResponse();
String content = null;
if (paramsArr == null || paramsArr.isEmpty()) {
// 固定短信发送
content = templateInfo.getUpContent();
} else {
// 变量短信发送
String upContent = templateInfo.getUpContent();
content = getMsg(upContent, paramList);
}
response = bgySmsService.sendSms(mobile, content);
String code = response.getCode();
String msg = response.getMsg();
// TODO 根据DM hub需要的返回数据封装
return new DmHubSendResponse(code, msg);
} catch (Exception e) {
log.error("调用短信发送逻辑错误", e);
return new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
}
/**
* 获取可以直接用户发送的短信内容
*
* @param upContent
* @param params
* @return
*/
private String getMsg(String upContent, List<String> params) {
for (String info : params) {
upContent = upContent.replaceFirst("\\{\\$var\\}", info);
}
return upContent;
}
@Override
public DmHubSendResponse batchSend(DmHubBatchSendRequest request) {
String batchId = request.getBatchId(); // DM hub 批次号
String templateId = request.getTemplateId(); // 此次短信对应的模板id
String audienceIdType = request.getAudienceIdType();
List<JSONObject> data = request.getData();
SmsTemplateInfo templateInfo = smsTemplateService.selectOne(new EntityWrapper<SmsTemplateInfo>().eq("dm_template_id", templateId));
if (null == templateInfo) {
return new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
// 模板参数占位符
String params = templateInfo.getParams();
JSONArray paramsArr = JSONArray.parseArray(params);
// 封装参数
// StringBuilder sendParams = new StringBuilder();
Map<String, List<String>> paramsMap = new HashMap();
int i = 0;
for (JSONObject json : data) {
i++;
Set<String> keys = json.keySet();
String mobile = json.getString("_audienceId");
json.remove("name");
json.remove("id");
json.remove("_audienceId");
if (!json.isEmpty()) {
for (Object parm : paramsArr) {
List<String> list = new ArrayList<>();
String s = parm.toString();
for (String key : keys) {
String newKey = key;
Object value = json.get(key);
if (value instanceof JSONObject || value instanceof Map) {
StringBuilder keyBuffer = new StringBuilder(key);
value = getKeyValue(value, keyBuffer);
newKey = keyBuffer.toString();
}
if (s.contains(newKey)) {
list.add(value.toString());
}
}
paramsMap.put(mobile, list);
}
} else {
if (i != data.size()) {
paramsMap.put(mobile, new ArrayList<>());
}
}
}
DmBatchInfo dmInfo = new DmBatchInfo();
dmInfo.setDmBatchId(batchId);
dmInfo.setDmTemplateId(templateId);
dmInfo.setSmsNum(data.size());
dmInfo.setId(IdHandler.nextId());
dmInfo.setDateCreated(new Date());
dmInfo.setLastUpdated(new Date());
dmBatchService.insert(dmInfo);
SysBatchInfo info = new SysBatchInfo();
info.setId(info.getBatchId());
info.setDmBatchId(batchId);
info.setSmsNum(data.size());
info.setDmTemplateId(templateId);
Long sysBatchId = IdHandler.nextId();
info.setBatchId(sysBatchId);
info.setDateCreated(new Date());
info.setLastUpdated(new Date());
sysBatchService.insert(info);
CLBizResponse response = new CLBizResponse();
if (paramsArr == null || paramsArr.isEmpty()) {
try {
// response = bgySmsService.sendSms("", templateInfo.getUpContent());
String code = response.getCode();
String msg = response.getMsg();
// TODO 根据DM hub需要的返回数据封装
if (ResponseCode.SUCCESS.getCode().equals(code)) {
return new DmHubSendResponse(code, msg);
} else {
return new DmHubSendResponse(code, msg);
}
} catch (Exception e) {
log.error("调用创蓝逻辑错误", e);
// TODO 根据DM hub需要的返回数据封装
return new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
} else {
// 固定短信
Set<Map.Entry<String, List<String>>> entries = paramsMap.entrySet();
try {
// 此处不做拆分操作
// for (Map.Entry<String, List<String>> entry : entries) {
// String mobile = entry.getKey().toString();
// List<String> paramsList = entry.getValue();
// String sendMsg = getMsg(templateInfo.getUpContent(), paramsList);
// response = bgySmsService.sendSms(mobile, sendMsg);
// String code = response.getCode();
// String msg = response.getMsg();
// }
// TODO 待优化
return new DmHubSendResponse(ResponseCode.SUCCESS);
} catch (Exception e) {
log.error("调用创蓝逻辑错误:", e);
return new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
}
}
@Override
public DmHubSendResponse batchSendOneByOne(DmHubBatchSendRequest request) {
String batchId = request.getBatchId(); // DM hub 批次号
String templateId = request.getTemplateId(); // 此次短信对应的模板id
String audienceIdType = request.getAudienceIdType();
List<JSONObject> data = request.getData();
SmsTemplateInfo templateInfo = smsTemplateService.selectOne(new EntityWrapper<SmsTemplateInfo>().eq("dm_template_id", templateId));
if (null == templateInfo) {
return new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
// 模板参数占位符
String params = templateInfo.getParams();
JSONArray paramsArr = JSONArray.parseArray(params);
// 封装参数
List<String> mobileList = new ArrayList<>();
Map<String, List<String>> paramsMap = new HashMap();
int i = 0;
for (JSONObject json : data) {
i++;
Set<String> keys = json.keySet();
String mobile = json.getString("_audienceId");
json.remove("name");
json.remove("id");
json.remove("_audienceId");
if (!json.isEmpty()) {
for (Object parm : paramsArr) {
List<String> list = new ArrayList<>();
String s = parm.toString();
for (String key : keys) {
String newKey = key;
Object value = json.get(key);
if (value instanceof JSONObject || value instanceof Map) {
StringBuilder keyBuffer = new StringBuilder(key);
value = getKeyValue(value, keyBuffer);
newKey = keyBuffer.toString();
}
if (s.contains(newKey)) {
list.add(value.toString());
}
}
paramsMap.put(mobile, list);
}
} else {
if (i != data.size()) {
paramsMap.put(mobile, new ArrayList<>());
}
}
}
DmBatchInfo dmInfo = new DmBatchInfo();
dmInfo.setDmBatchId(batchId);
dmInfo.setDmTemplateId(templateId);
dmInfo.setSmsNum(data.size());
dmInfo.setId(IdHandler.nextId());
dmInfo.setDateCreated(new Date());
dmInfo.setLastUpdated(new Date());
dmBatchService.insert(dmInfo);
SysBatchInfo info = new SysBatchInfo();
info.setId(info.getBatchId());
info.setDmBatchId(batchId);
info.setSmsNum(data.size());
info.setDmTemplateId(templateId);
Long sysBatchId = IdHandler.nextId();
info.setBatchId(sysBatchId);
info.setDateCreated(new Date());
info.setLastUpdated(new Date());
sysBatchService.insert(info);
CLBizResponse response = new CLBizResponse();
if (paramsArr == null || paramsArr.isEmpty()) {
try {
for (String mobile : mobileList) {
response = bgySmsService.sendSms("", templateInfo.getUpContent());
}
} catch (Exception e) {
log.error("调用创蓝逻辑错误", e);
// TODO 根据DM hub需要的返回数据封装
return new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
} else {
// 变量短信
Set<Map.Entry<String, List<String>>> entries = paramsMap.entrySet();
try {
for (Map.Entry<String, List<String>> entry : entries) {
String mobile = entry.getKey().toString();
List<String> paramsList = entry.getValue();
String sendMsg = getMsg(templateInfo.getUpContent(), paramsList);
response = bgySmsService.sendSms(mobile, sendMsg);
String code = response.getCode();
String msg = response.getMsg();
}
// TODO 待优化
return new DmHubSendResponse(ResponseCode.SUCCESS);
} catch (Exception e) {
log.error("调用创蓝逻辑错误:", e);
return new DmHubSendResponse(ResponseCode.SYSTEM_ERROR);
}
}
return new DmHubSendResponse(ResponseCode.SUCCESS);
}
private String getKeyValue(Object value, StringBuilder keyBuffer) {
String s = JSONObject.toJSONString(value);
JSONObject valueJson = JSONObject.parseObject(s);
Set<String> set = valueJson.keySet();
if (set.isEmpty()) {
return value.toString();
}
for (String str : set) {
keyBuffer.append(".").append(str);
Object info = valueJson.get(str);
if (info instanceof JSONObject || info instanceof Map) {
String test = getKeyValue(info, keyBuffer);
return test;
} else {
return info.toString();
}
}
return value.toString();
}
}
package com.bgy.sms.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.bgy.sms.repository.domain.SmsTemplateInfo;
import com.bgy.sms.repository.mapper.TemplateMapper;
import com.bgy.sms.service.SmsTemplateService;
import org.springframework.stereotype.Service;
@Service
public class SmsTemplateServiceImpl extends ServiceImpl<TemplateMapper, SmsTemplateInfo> implements SmsTemplateService {
}
package com.bgy.sms.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.bgy.sms.repository.domain.SysBatchInfo;
import com.bgy.sms.repository.mapper.SysBatchMapper;
import com.bgy.sms.service.SysBatchService;
import org.springframework.stereotype.Service;
@Service
public class SysBatchServiceImpl extends ServiceImpl<SysBatchMapper, SysBatchInfo> implements SysBatchService {
}
package com.bgy.util;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class HttpUtil {
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
public static String doPost(String url, Map params) {
BufferedReader in = null;
try {
// 定义HttpClient
CloseableHttpClient build = HttpClientBuilder.create().build();
// 实例化HTTP方法
HttpPost request = new HttpPost();
request.setURI( new URI( url ) );
//设置参数
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
for (Iterator iter = params.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String value = String.valueOf( params.get( name ) );
nvps.add( new BasicNameValuePair( name, value ) );
//System.out.println(name +"-"+value);
}
request.setEntity( new UrlEncodedFormEntity( nvps, HTTP.UTF_8 ) );
HttpResponse response = build.execute( request );
int code = response.getStatusLine().getStatusCode();
if (code == 200) { //请求成功
in = new BufferedReader( new InputStreamReader( response.getEntity()
.getContent(), "utf-8" ) );
StringBuffer sb = new StringBuffer( "" );
String line = "";
String NL = System.getProperty( "line.separator" );
while ((line = in.readLine()) != null) {
sb.append( line + NL );
}
in.close();
return sb.toString();
} else { //
System.out.println( "状态码:" + code );
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
package com.bgy.util;
import java.security.MessageDigest;
public class Md5Util {
//盐,用于混交md5
public static String encrypt(String dataStr) {
try {
MessageDigest m = MessageDigest.getInstance("MD5");
m.update(dataStr.getBytes("UTF8"));
byte s[] = m.digest();
String result = "";
for (int i = 0; i < s.length; i++) {
result += Integer.toHexString((0x000000FF & s[i]) | 0xFFFFFF00).substring(6);
}
return result;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
package com.bgy.util;
import com.baomidou.mybatisplus.toolkit.MapUtils;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Iterator;
import java.util.Map;
@Component
public class OkHttpUtil {
private static final Logger log = LoggerFactory.getLogger(OkHttpUtil.class);
private static OkHttpClient okHttpClient;
@Autowired
public OkHttpUtil(OkHttpClient okHttpClient) {
OkHttpUtil.okHttpClient = okHttpClient;
}
/**
* get
*
* @param url 请求的url
* @param queries 请求的参数,在浏览器?后面的数据,没有可以传null
* @return
*/
public static String get(String url, Map<String, String> queries) {
String responseBody = "";
StringBuffer sb = new StringBuffer(url);
if (MapUtils.isNotEmpty(queries)) {
boolean firstFlag = true;
Iterator iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry<String, String>) iterator.next();
if (firstFlag) {
sb.append("?" + entry.getKey() + "=" + entry.getValue());
firstFlag = false;
} else {
sb.append("&" + entry.getKey() + "=" + entry.getValue());
}
}
}
Request request = new Request.Builder().url(sb.toString()).build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
//int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
log.error("okhttp3 put error >> ex = {}", e);
} finally {
if (response != null) {
response.close();
}
}
return responseBody;
}
/**
* Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"} 参数一:请求Url 参数二:请求的JSON
* 参数三:请求回调
*/
public static String postJsonParams(String url, String jsonParams) {
String responseBody = "";
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
Request request = new Request.Builder().url(url).post(requestBody).build();
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
// int status = response.code();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
log.error("okhttp3 post error >> ex = {}", e);
} finally {
if (response != null) {
response.close();
}
}
return responseBody;
}
}
package com.bgy.util.id;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 基于Twitter的Snowflake算法实现分布式高效有序ID生产黑科技(sequence)
*
* <br>
* SnowFlake的结构如下(每部分用-分开):<br>
* <br>
* 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
* <br>
* 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
* <br>
* 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
* 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
* <br>
* 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
* <br>
* 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
* <br>
* <br>
* 加起来刚好64位,为一个Long型。<br>
* SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
*
* @author lry
* @modify shuliangxing
* @see <a href="https://tech.meituan.com/MT_Leaf.html">常见id策略对比分析</a>
* @see <a href="https://github.com/twitter/snowflake">twitter snowflake</a>
* @see <a href="https://gitee.com/yu120/sequence">sequence</a>
*/
public class Id {
/**
* 起始时间戳,用于用当前时间戳减去这个时间戳,算出偏移量
**/
// 某一时刻时间戳, 2018-05-01 00:00:00 1525104000000
private final long startTime = 1525104000000L;
/**
* workerId占用的位数5(表示只允许workId的范围为:0-1023)
**/
private final long workerIdBits = 5L;
/**
* dataCenterId占用的位数:5
**/
private final long dataCenterIdBits = 5L;
/**
* 序列号占用的位数:12(表示只允许workId的范围为:0-4095)
**/
private final long sequenceBits = 12L;
/**
* workerId可以使用的最大数值:31
**/
private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
/**
* dataCenterId可以使用的最大数值:31
**/
private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);
private final long workerIdShift = sequenceBits;
private final long dataCenterIdShift = sequenceBits + workerIdBits;
private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;
/**
* 用mask防止溢出:位与运算保证计算的结果范围始终是 0-4095
**/
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
private long workerId;
private long dataCenterId;
private long sequence = 0L;
private long lastTimestamp = -1L;
private boolean isClock = false;
/**
* 基于Snowflake创建分布式ID生成器
* <p>
* 注:sequence
*
* @param workerId 工作机器ID,数据范围为0~31
* @param dataCenterId 数据中心ID,数据范围为0~31
*/
public Id(long workerId, long dataCenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
throw new IllegalArgumentException(String.format("dataCenter Id can't be greater than %d or less than 0", maxDataCenterId));
}
this.workerId = workerId;
this.dataCenterId = dataCenterId;
}
public void setClock(boolean clock) {
isClock = clock;
}
/**
* 获取ID
*
* @return
*/
public synchronized Long nextId() {
long timestamp = this.timeGen();
// 闰秒:如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
if (timestamp < lastTimestamp) {
long offset = lastTimestamp - timestamp;
if (offset <= 5) {
try {
this.wait(offset << 1);
timestamp = this.timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset));
}
}
// 解决跨毫秒生成ID序列号始终为偶数的缺陷:如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
// 通过位与运算保证计算的结果范围始终是 0-4095
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = this.tilNextMillis(lastTimestamp);
}
} else {
// 时间戳改变,毫秒内序列重置
sequence = 0L;
}
lastTimestamp = timestamp;
/*
* 1.左移运算是为了将数值移动到对应的段(41、5、5,12那段因为本来就在最右,因此不用左移)
* 2.然后对每个左移后的值(la、lb、lc、sequence)做位或运算,是为了把各个短的数据合并起来,合并成一个二进制数
* 3.最后转换成10进制,就是最终生成的id
*/
return ((timestamp - startTime) << timestampLeftShift) |
(dataCenterId << dataCenterIdShift) |
(workerId << workerIdShift) |
sequence;
}
/**
* 保证返回的毫秒数在参数之后(阻塞到下一个毫秒,直到获得新的时间戳)
*
* @param lastTimestamp
* @return
*/
private long tilNextMillis(long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return timestamp;
}
/**
* 获得系统当前毫秒数
*
* @return timestamp
*/
private long timeGen() {
if (isClock) {
// 解决高并发下获取时间戳的性能问题
return SystemClock.now();
} else {
return System.currentTimeMillis();
}
}
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2018-05-01 00:00:00"); //1525104000000
System.out.println("\r\n----------Id.main()----------sdf.format(date)=" + sdf.format(date));
System.out.println("\r\n----------Id.main()----------date.getTime()=" + date.getTime());
}
}
\ No newline at end of file
package com.bgy.util.id;
public class IdHandler {
private IdHandler() {
super();
}
private static final Id id = new Id(0, 0);
public static Id getInstance() {
return id;
}
public static long nextId() {
return id.nextId();
}
public static String nextIdStr() {
return String.valueOf(nextId());
}
public static void main(String[] args) {
}
}
package com.bgy.util.id;
import java.sql.Timestamp;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* 高并发场景下System.currentTimeMillis()的性能问题的优化
* <p><p>
* System.currentTimeMillis()的调用比new一个普通对象要耗时的多(具体耗时高出多少我还没测试过,有人说是100倍左右)<p>
* System.currentTimeMillis()之所以慢是因为去跟系统打了一次交道<p>
* 后台定时更新时钟,JVM退出时,线程自动回收<p>
* 10亿:43410,206,210.72815533980582%<p>
* 1亿:4699,29,162.0344827586207%<p>
* 1000万:480,12,40.0%<p>
* 100万:50,10,5.0%<p>
*
* @author lry
*/
public class SystemClock {
private final long period;
private final AtomicLong now;
private SystemClock(long period) {
this.period = period;
this.now = new AtomicLong(System.currentTimeMillis());
scheduleClockUpdating();
}
private static class InstanceHolder {
public static final SystemClock INSTANCE = new SystemClock(1);
}
private static SystemClock instance() {
return InstanceHolder.INSTANCE;
}
private void scheduleClockUpdating() {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable, "System Clock");
thread.setDaemon(true);
return thread;
}
});
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
now.set(System.currentTimeMillis());
}
}, period, period, TimeUnit.MILLISECONDS);
}
private long currentTimeMillis() {
return now.get();
}
public static long now() {
return instance().currentTimeMillis();
}
public static String nowDate() {
return new Timestamp(instance().currentTimeMillis()).toString();
}
}
...@@ -4,14 +4,13 @@ server: ...@@ -4,14 +4,13 @@ server:
port: 9010 port: 9010
#contextPath: /resource #contextPath: /resource
spring: spring:
datasource: datasource:
type: com.zaxxer.hikari.HikariDataSource type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://127.0.0.1:3306/plugin?characterEncoding=utf8&useSSL=false url: jdbc:mysql://119.23.32.151:3306/dmhub_plugin?characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
username: root username: dmp
password: root password: Ioubuy@2019@!
hikari: hikari:
maxLifetime: 1765000 maxLifetime: 1765000
maximumPoolSize: 20 maximumPoolSize: 20
...@@ -21,24 +20,18 @@ spring: ...@@ -21,24 +20,18 @@ spring:
redis: redis:
database: 0 database: 0
host: 127.0.0.1 host: 119.23.32.151
port: 6379 port: 8007
timeout: 5000 timeout: 5000
system: system:
config: config:
chuanglan: bgy:
notificationAccount: N0767543 # 通知类短信账号 appId: 2021 # 系统id
notificationPassword: N0767543 # 通知类短信密码 securityCode: 930844c7-7985-435b-af47-142b59b299c3 # 鉴权码
marketingAccount: M7603731 # 营销类短信账号 url: https://xstest.bgy.com.cn/ApiBgyTest/Open/Sms.ashx
marketingPassword: N0767543 # 营销类短信密码 areaId: XXJSB
sendFixed: http://smssh1.253.com/msg/send/json # 短信下发接口 api: SendSms
sendVariable: http://smssh1.253.com/msg/variable/json # 变量短信下发接口
reportUrl: http://test.9z.com/msg/report # 短信报告
pullReport: http://smssh1.253.com/msg/pull/report # 拉取短信报告
addTemplate: https://zz.253.com/apis/template/add # 创建短信模板
interfaceUser: admin001 # 接口用户名
interfacePassword: 9zdata0423 # 接口密码
dmHub: dmHub:
applicationId: cl0300171a6012c21 applicationId: cl0300171a6012c21
applicationKey: 4017078e9dfd593b2d9a0ede58eff589644fbe50 applicationKey: 4017078e9dfd593b2d9a0ede58eff589644fbe50
......
...@@ -3,17 +3,18 @@ ...@@ -3,17 +3,18 @@
server: server:
tomcat: tomcat:
max-threads: 50 max-threads: 50
port: 19010 port: 15600
#contextPath: /resource #contextPath: /resource
spring: spring:
datasource: datasource:
type: com.zaxxer.hikari.HikariDataSource type: com.zaxxer.hikari.HikariDataSource
url: jdbc:mysql://119.23.32.151:3306/dmhub_plugin?characterEncoding=utf8&useSSL=false # url: jdbc:mysql://119.23.32.151:3306/dmhub_plugin?characterEncoding=utf8&useSSL=false
url: jdbc:mysql://my09457h.mysql.db.pcloud.localdomain:3070/dmhub_plugin?characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
username: dmp username: bu00310
password: Ioubuy@2019@! password: pwd$BU00310
hikari: hikari:
maxLifetime: 1765000 maxLifetime: 1765000
maximumPoolSize: 20 maximumPoolSize: 20
...@@ -24,23 +25,17 @@ spring: ...@@ -24,23 +25,17 @@ spring:
redis: redis:
database: 0 database: 0
host: 127.0.0.1 host: rs67xf4p.redisrep.db.pcloud.localdomain
port: 6379 port: 16034
timeout: 5000 timeout: 5000
system: system:
config: config:
chuanglan: bgy:
notificationAccount: N0767543 # 通知类短信账号 appId: 2021 # 系统id
notificationPassword: DaejS7P5ixaeee # 通知类短信密码 securityCode: 930844c7-7985-435b-af47-142b59b299c3 # 鉴权码
marketingAccount: M7603731 # 营销类短信账号 url: https://xstest.bgy.com.cn/ApiBgyTest/Open/Sms.ashx
marketingPassword: N0767543 # 营销类短信密码 areaId: XXJSB
sendFixed: http://smssh1.253.com/msg/send/json # 短信下发接口 api: SendSms
sendVariable: http://smssh1.253.com/msg/variable/json # 变量短信下发接口
reportUrl: http://test.9z.com/msg/report # 短信报告
pullReport: http://smssh1.253.com/msg/pull/report # 拉取短信报告
addTemplate: https://zz.253.com/apis/template/add # 创建短信模板
interfaceUser: admin001 # 接口用户名
interfacePassword: 9zdata0423 # 接口密码
dmHub: dmHub:
applicationId: cl0300171a6012c21 applicationId: cl0300171a6012c21
applicationKey: 4017078e9dfd593b2d9a0ede58eff589644fbe50 applicationKey: 4017078e9dfd593b2d9a0ede58eff589644fbe50
......
...@@ -8,11 +8,11 @@ info: ...@@ -8,11 +8,11 @@ info:
spring: spring:
profiles: profiles:
active: test active: prod
mybatis-plus: mybatis-plus:
mapper-locations: classpath:mapper/*.xml mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.jz.sms.repository.domain type-aliases-package: com.bgy.sms.repository.domain
configuration: configuration:
map-underscore-to-camel-case: true map-underscore-to-camel-case: true
......
...@@ -22,12 +22,12 @@ ...@@ -22,12 +22,12 @@
<!-- 开发、测试环境 --> <!-- 开发、测试环境 -->
<springProfile name="dev,test"> <springProfile name="dev,test">
<logger name="org.springboot.sample" level="DEBUG" /> <logger name="org.springboot.sample" level="DEBUG" />
<logger name="com.jz" level="DEBUG" /> <logger name="com.bgy" level="DEBUG" />
</springProfile> </springProfile>
<!-- 生产环境 --> <!-- 生产环境 -->
<springProfile name="prod"> <springProfile name="prod">
<logger name="org.springframework.web" level="ERROR"/> <logger name="org.springframework.web" level="ERROR"/>
<logger name="org.springboot.sample" level="ERROR" /> <logger name="org.springboot.sample" level="ERROR" />
<logger name="com.jz" level="ERROR" /> <logger name="com.bgy" level="ERROR" />
</springProfile> </springProfile>
</configuration> </configuration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jz.sms.repository.mapper.MessageMapper"> <mapper namespace="com.bgy.sms.repository.mapper.MessageMapper">
</mapper> </mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jz.sms.repository.mapper.SysBatchMapper"> <mapper namespace="com.bgy.sms.repository.mapper.SysBatchMapper">
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jz.sms.repository.mapper.TemplateMapper"> <mapper namespace="com.bgy.sms.repository.mapper.TemplateMapper">
<resultMap id="baseMap" type="com.jz.sms.repository.domain.SmsTemplateInfo"> <resultMap id="baseMap" type="com.bgy.sms.repository.domain.SmsTemplateInfo">
<id column="id" property="id" /> <id column="id" property="id" />
<id column="dm_template_id" property="dmTemplateId" /> <id column="dm_template_id" property="dmTemplateId" />
<id column="type" property="type" /> <id column="type" property="type" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment