|
|
@@ -98,6 +98,224 @@ public class SmsServiceImpl implements ISmsService
|
|
|
@Autowired
|
|
|
private BalanceService balanceService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private com.fs.proxy.service.ICompanySmsPortService smsPortService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private com.fs.proxy.mapper.CompanySmsApiMapper smsApiMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private com.fs.proxy.mapper.CompanySmsApiTenantMapper smsApiTenantMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private com.fs.proxy.mapper.CompanySmsCardMiddlewareMapper smsCardMiddlewareMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private com.fs.proxy.mapper.CompanySmsCardMapper smsCardMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 统一发送方法 - 替代原来6处硬编码的 his.sms 配置读取
|
|
|
+ *
|
|
|
+ * @param phone 目标手机号
|
|
|
+ * @param content 短信内容
|
|
|
+ * @param tempType 模板类型: 1=行业通知 2=营销短信
|
|
|
+ * @param tenantId 租户ID
|
|
|
+ * @param companyUserId 销售人员ID(可为null)
|
|
|
+ * @param preferApiId 销售手动选择的接口ID(可为null, null则自动路由)
|
|
|
+ * @return 发送结果 "OK"=成功, 其他=错误信息
|
|
|
+ */
|
|
|
+ private String resolveAndSend(String phone, String content, Integer tempType,
|
|
|
+ Long tenantId, Long companyUserId, Long preferApiId) {
|
|
|
+ // 将模板类型映射到短信发送类型: tempType 1=行业 → smsType 1; tempType 2=营销 → smsType 2
|
|
|
+ Integer smsType = tempType;
|
|
|
+
|
|
|
+ // 1. 通过端口服务解析可用端口(含降级路由逻辑)
|
|
|
+ com.fs.proxy.domain.CompanySmsApiPort port = smsPortService.resolvePort(tenantId, smsType, companyUserId, preferApiId);
|
|
|
+ if (port == null) {
|
|
|
+ log.warn("resolveAndSend: 无可用端口 tenantId={}, smsType={}, userId={}", tenantId, smsType, companyUserId);
|
|
|
+ return "NO_AVAILABLE_PORT";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 获取接口信息
|
|
|
+ com.fs.proxy.domain.CompanySmsApi api = smsApiMapper.selectSmsApiById(port.getApiId());
|
|
|
+ if (api == null) {
|
|
|
+ log.error("resolveAndSend: 接口不存在 apiId={}", port.getApiId());
|
|
|
+ return "API_NOT_FOUND";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 确定实际使用的账户/密码/签名(端口级优先, 接口级兜底)
|
|
|
+ String useAccount = StringUtils.isNotEmpty(port.getAccount()) ? port.getAccount() : api.getAccount();
|
|
|
+ String usePassword = StringUtils.isNotEmpty(port.getPassword()) ? port.getPassword() : api.getPassword();
|
|
|
+ String useSign = StringUtils.isNotEmpty(port.getSign()) ? port.getSign() : api.getSign();
|
|
|
+ String useUrl = api.getUrl();
|
|
|
+
|
|
|
+ // 4. 根据provider分发
|
|
|
+ String provider = api.getProvider();
|
|
|
+ log.info("resolveAndSend: provider={}, apiId={}, portId={}, phone={}", provider, api.getApiId(), port.getPortId(), phone);
|
|
|
+
|
|
|
+ if ("rf".equals(provider)) {
|
|
|
+ // 润方发送
|
|
|
+ return sendByRf(phone, content, tempType, useAccount, usePassword, useSign, useUrl, port.getPortNo(), tenantId, api.getApiId(), port.getPortId());
|
|
|
+ } else if ("dh".equals(provider)) {
|
|
|
+ // 德华发送
|
|
|
+ return sendByDh(phone, content, tempType, useAccount, usePassword, tenantId, api.getApiId(), port.getPortId());
|
|
|
+ } else if ("card".equals(provider)) {
|
|
|
+ // 手机卡发送
|
|
|
+ return sendByCard(phone, content, tenantId, api.getApiId(), port.getPortId(), companyUserId);
|
|
|
+ } else {
|
|
|
+ log.error("resolveAndSend: 未知provider={} apiId={}", provider, api.getApiId());
|
|
|
+ return "UNKNOWN_PROVIDER";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 润方发送 */
|
|
|
+ private String sendByRf(String phone, String content, Integer tempType,
|
|
|
+ String account, String password, String sign, String url, String extno,
|
|
|
+ Long tenantId, Long apiId, Long portId) {
|
|
|
+ String urls;
|
|
|
+ try {
|
|
|
+ if (tempType.equals(1)) {
|
|
|
+ urls = url + "sms?action=send&account=" + account + "&password=" + password
|
|
|
+ + "&mobile=" + phone + "&content=" + URLEncoder.encode(sign + content, "UTF-8")
|
|
|
+ + "&extno=" + extno + "&rt=json";
|
|
|
+ } else if (tempType.equals(2)) {
|
|
|
+ urls = url + "sms?action=send&account=" + account + "&password=" + password
|
|
|
+ + "&mobile=" + phone + "&content=" + URLEncoder.encode(sign + content + "拒收请回复R", "UTF-8")
|
|
|
+ + "&extno=" + extno + "&rt=json";
|
|
|
+ } else {
|
|
|
+ return "UNSUPPORTED_TEMP_TYPE";
|
|
|
+ }
|
|
|
+ } catch (UnsupportedEncodingException e) {
|
|
|
+ log.error("sendByRf: URL编码异常", e);
|
|
|
+ return "ENCODE_ERROR";
|
|
|
+ }
|
|
|
+
|
|
|
+ String post = HttpRequest.get(urls).execute().body();
|
|
|
+ SmsSendVO vo = JSONUtil.toBean(post, SmsSendVO.class);
|
|
|
+ if (vo.getStatus().equals(0)) {
|
|
|
+ for (SmsSendItemVO itemVO : vo.getList()) {
|
|
|
+ if (itemVO.getResult().equals("0")) {
|
|
|
+ // 发送成功, 返回OK (调用方负责写日志)
|
|
|
+ return "OK";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "SEND_FAILED";
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 德华发送 */
|
|
|
+ private String sendByDh(String phone, String content, Integer tempType,
|
|
|
+ String account, String password,
|
|
|
+ Long tenantId, Long apiId, Long portId) {
|
|
|
+ SendSmsReturn sendSmsReturn;
|
|
|
+ if (tempType.equals(1)) {
|
|
|
+ sendSmsReturn = smsTService.sendSms(account, password, content, phone);
|
|
|
+ } else if (tempType.equals(2)) {
|
|
|
+ sendSmsReturn = smsTService.sendSms(account, password, content + "拒收请回复R", phone);
|
|
|
+ } else {
|
|
|
+ return "UNSUPPORTED_TEMP_TYPE";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sendSmsReturn != null && sendSmsReturn.getResult() != null && sendSmsReturn.getResult().equals("0")) {
|
|
|
+ return "OK";
|
|
|
+ }
|
|
|
+ return "SEND_FAILED";
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 手机卡发送(通过中间件) */
|
|
|
+ private String sendByCard(String phone, String content,
|
|
|
+ Long tenantId, Long apiId, Long portId, Long companyUserId) {
|
|
|
+ // 1. 查询该端口对应的在线卡
|
|
|
+ com.fs.proxy.domain.CompanySmsCard card = smsCardMapper.selectOnlineCardByPortId(portId);
|
|
|
+ if (card == null) {
|
|
|
+ log.warn("sendByCard: 无在线卡 portId={}", portId);
|
|
|
+ return "CARD_OFFLINE";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 短信发送限制检查
|
|
|
+ String limitCheck = checkCardSmsLimit(card);
|
|
|
+ if (limitCheck != null) {
|
|
|
+ log.warn("sendByCard: 卡限制检查未通过 cardId={}, reason={}", card.getCardId(), limitCheck);
|
|
|
+ return limitCheck;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 查中间件配置
|
|
|
+ com.fs.proxy.domain.CompanySmsCardMiddleware mw = smsCardMiddlewareMapper.selectMiddlewareByApiId(apiId);
|
|
|
+ if (mw == null) {
|
|
|
+ log.error("sendByCard: 中间件未配置 apiId={}", apiId);
|
|
|
+ return "MIDDLEWARE_NOT_FOUND";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 通过HTTP POST下发任务到中间件
|
|
|
+ try {
|
|
|
+ com.alibaba.fastjson.JSONObject task = new com.alibaba.fastjson.JSONObject();
|
|
|
+ task.put("phone", phone);
|
|
|
+ task.put("content", content);
|
|
|
+ task.put("tenantId", tenantId);
|
|
|
+ task.put("portId", portId);
|
|
|
+ task.put("cardId", card.getCardId());
|
|
|
+ task.put("companyUserId", companyUserId);
|
|
|
+ task.put("senderPhone", card.getPhone1());
|
|
|
+ task.put("timestamp", System.currentTimeMillis());
|
|
|
+
|
|
|
+ String result = cn.hutool.http.HttpRequest.post(mw.getCallbackUrl())
|
|
|
+ .header("Authorization", "Bearer " + mw.getAuthToken())
|
|
|
+ .body(task.toJSONString())
|
|
|
+ .timeout(mw.getTimeoutSeconds() * 1000)
|
|
|
+ .execute().body();
|
|
|
+ log.info("sendByCard: 中间件响应={}", result);
|
|
|
+
|
|
|
+ // 5. 发送成功后递增短信计数
|
|
|
+ smsCardMapper.incrementSmsCount(card.getCardId());
|
|
|
+ return "OK";
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("sendByCard: 中间件调用失败", e);
|
|
|
+ return "MIDDLEWARE_ERROR";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查卡的短信发送限制
|
|
|
+ * @return null=通过, 非null=限制原因
|
|
|
+ */
|
|
|
+ private String checkCardSmsLimit(com.fs.proxy.domain.CompanySmsCard card) {
|
|
|
+ java.util.Date now = new java.util.Date();
|
|
|
+ java.util.Date today = org.apache.commons.lang3.time.DateUtils.truncate(now, java.util.Calendar.DAY_OF_MONTH);
|
|
|
+
|
|
|
+ // 检查剩余短信余额
|
|
|
+ if (card.getSmsBalance() != null && card.getSmsBalance() <= 0) {
|
|
|
+ return "CARD_SMS_BALANCE_EXHAUSTED";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查每日限制
|
|
|
+ if (card.getSmsDailyLimit() != null && card.getSmsDailyLimit() > 0) {
|
|
|
+ int sentToday = 0;
|
|
|
+ // 如果日期不是今天, 说明需要重置
|
|
|
+ if (card.getSmsSentDate() != null && org.apache.commons.lang3.time.DateUtils.isSameDay(card.getSmsSentDate(), now)) {
|
|
|
+ sentToday = card.getSmsSentToday() != null ? card.getSmsSentToday() : 0;
|
|
|
+ }
|
|
|
+ if (sentToday >= card.getSmsDailyLimit()) {
|
|
|
+ return "CARD_DAILY_LIMIT_EXCEEDED";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查每小时限制
|
|
|
+ if (card.getSmsHourlyLimit() != null && card.getSmsHourlyLimit() > 0) {
|
|
|
+ int currentHour = new java.util.GregorianCalendar().get(java.util.Calendar.HOUR_OF_DAY);
|
|
|
+ int sentHour = 0;
|
|
|
+ // 如果日期是今天且小时数匹配, 才使用当前小时计数
|
|
|
+ if (card.getSmsSentDate() != null && org.apache.commons.lang3.time.DateUtils.isSameDay(card.getSmsSentDate(), now)
|
|
|
+ && card.getSmsSentHourNum() != null && card.getSmsSentHourNum() == currentHour) {
|
|
|
+ sentHour = card.getSmsSentHour() != null ? card.getSmsSentHour() : 0;
|
|
|
+ }
|
|
|
+ if (sentHour >= card.getSmsHourlyLimit()) {
|
|
|
+ return "CARD_HOURLY_LIMIT_EXCEEDED";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null; // 通过
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public R sendTSms(String mobile, String code) {
|
|
|
// try{
|
|
|
@@ -231,6 +449,8 @@ public class SmsServiceImpl implements ISmsService
|
|
|
if(StringUtils.isNotEmpty(UserName)){
|
|
|
content=content.replace("${sms.csName}",UserName);
|
|
|
}
|
|
|
+ // sendUserSms为系统级发送(无companyId), 回退到全局配置
|
|
|
+ // TODO: 后续如需支持租户级, 可在此处获取companyId后调用resolveAndSend
|
|
|
String urls= null;
|
|
|
SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.sms");
|
|
|
FsSmsConfig sms = JSON.parseObject(sysConfig.getConfigValue(), FsSmsConfig.class);
|
|
|
@@ -336,85 +556,25 @@ public class SmsServiceImpl implements ISmsService
|
|
|
if(StringUtils.isNotEmpty(param.getCardUrl())){
|
|
|
content=content.replace("${sms.cardUrl}",param.getCardUrl());
|
|
|
}
|
|
|
- String urls= null;
|
|
|
- SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.sms");
|
|
|
- FsSmsConfig sms = JSON.parseObject(sysConfig.getConfigValue(), FsSmsConfig.class);
|
|
|
- if (sms.getType().equals("rf")){
|
|
|
- try {
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- urls = sms.getRfUrl1()+"sms?action=send&account="+sms.getRfAccount1()+"&password="+sms.getRfPassword1()+"&mobile="+fsStoreOrder.getUserPhone()+"&content="+ URLEncoder.encode(sms.getRfSign()+content, "UTF-8")+"&extno="+sms.getRfCode1()+"&rt=json";
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- urls = sms.getRfUrl2()+"sms?action=send&account="+sms.getRfAccount2()+"&password="+sms.getRfPassword2()+"&mobile="+fsStoreOrder.getUserPhone()+"&content="+ URLEncoder.encode(sms.getRfSign()+content+"拒收请回复R", "UTF-8")+"&extno="+sms.getRfCode2()+"&rt=json";
|
|
|
- }
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- String post = HttpRequest.get(urls)
|
|
|
-// .body(String.valueOf(jsonObject))
|
|
|
- .execute().body();
|
|
|
- SmsSendVO vo=JSONUtil.toBean(post, SmsSendVO.class);
|
|
|
- if(vo.getStatus().equals(0)){
|
|
|
- for(SmsSendItemVO itemVO:vo.getList()){
|
|
|
- if(itemVO.getResult().equals("0")){
|
|
|
- CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
- logs.setCompanyId(param.getCompanyId());
|
|
|
- logs.setContent(content);
|
|
|
- logs.setTempCode(temp.getTempCode());
|
|
|
- logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
- logs.setTempId(temp.getTempId());
|
|
|
- logs.setPhone(fsStoreOrder.getUserPhone());
|
|
|
- logs.setSendTime(new Date());
|
|
|
- logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- logs.setMid(itemVO.getMid());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
- logs.setNumber(counts);
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }else if (sms.getType().equals("dh")){
|
|
|
- SendSmsReturn sendSmsReturn =null;
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- sendSmsReturn = smsTService.sendSms(sms.getDhAccount1(), sms.getDhPassword1(), content, fsStoreOrder.getUserPhone());
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- sendSmsReturn= smsTService.sendSms(sms.getDhAccount2(),sms.getDhPassword2(),content+"拒收请回复R",fsStoreOrder.getUserPhone());
|
|
|
- }
|
|
|
- System.out.println(sendSmsReturn);
|
|
|
- if (sendSmsReturn!=null){
|
|
|
- if (sendSmsReturn.getResult()!=null&&sendSmsReturn.getResult().equals("0")){
|
|
|
- CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
- logs.setCompanyId(param.getCompanyId());
|
|
|
- logs.setContent(content);
|
|
|
- logs.setTempCode(temp.getTempCode());
|
|
|
- logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
- logs.setTempId(temp.getTempId());
|
|
|
- logs.setPhone(fsStoreOrder.getUserPhone());
|
|
|
- logs.setSendTime(new Date());
|
|
|
- logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- logs.setMid(sendSmsReturn.getMsgid());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
- logs.setNumber(counts);
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
- }
|
|
|
- }
|
|
|
+ // ===== 动态路由发送 =====
|
|
|
+ String sendResult = resolveAndSend(fsStoreOrder.getUserPhone(), content, temp.getTempType(),
|
|
|
+ param.getCompanyId(), param.getCompanyUserId(), null);
|
|
|
+ if ("OK".equals(sendResult)) {
|
|
|
+ CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
+ logs.setCompanyId(param.getCompanyId());
|
|
|
+ logs.setContent(content);
|
|
|
+ logs.setTempCode(temp.getTempCode());
|
|
|
+ logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
+ logs.setTempId(temp.getTempId());
|
|
|
+ logs.setPhone(fsStoreOrder.getUserPhone());
|
|
|
+ logs.setSendTime(new Date());
|
|
|
+ logs.setStatus(0);
|
|
|
+ Integer counts = content.length()/67;
|
|
|
+ if(content.length()%67>0) counts++;
|
|
|
+ if(counts==0) counts=1;
|
|
|
+ logs.setNumber(counts);
|
|
|
+ smsLogsService.insertCompanySmsLogs(logs);
|
|
|
+ companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
}
|
|
|
|
|
|
return R.ok("短信提交成功,正在发送中...");
|
|
|
@@ -459,85 +619,25 @@ public class SmsServiceImpl implements ISmsService
|
|
|
if(StringUtils.isNotEmpty(param.getCardUrl())){
|
|
|
content=content.replace("${sms.cardUrl}",param.getCardUrl());
|
|
|
}
|
|
|
- String urls= null;
|
|
|
- SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.sms");
|
|
|
- FsSmsConfig sms = JSON.parseObject(sysConfig.getConfigValue(), FsSmsConfig.class);
|
|
|
- if (sms.getType().equals("rf")){
|
|
|
- try {
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- urls = sms.getRfUrl1()+"sms?action=send&account="+sms.getRfAccount1()+"&password="+sms.getRfPassword1()+"&mobile="+packageOrder.getPhone()+"&content="+ URLEncoder.encode(sms.getRfSign()+content, "UTF-8")+"&extno="+sms.getRfCode1()+"&rt=json";
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- urls = sms.getRfUrl2()+"sms?action=send&account="+sms.getRfAccount2()+"&password="+sms.getRfPassword2()+"&mobile="+packageOrder.getPhone()+"&content="+ URLEncoder.encode(sms.getRfSign()+content+"拒收请回复R", "UTF-8")+"&extno="+sms.getRfCode2()+"&rt=json";
|
|
|
- }
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- String post = HttpRequest.get(urls)
|
|
|
-// .body(String.valueOf(jsonObject))
|
|
|
- .execute().body();
|
|
|
- SmsSendVO vo=JSONUtil.toBean(post, SmsSendVO.class);
|
|
|
- if(vo.getStatus().equals(0)){
|
|
|
- for(SmsSendItemVO itemVO:vo.getList()){
|
|
|
- if(itemVO.getResult().equals("0")){
|
|
|
- CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
- logs.setCompanyId(param.getCompanyId());
|
|
|
- logs.setContent(content);
|
|
|
- logs.setTempCode(temp.getTempCode());
|
|
|
- logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
- logs.setTempId(temp.getTempId());
|
|
|
- logs.setPhone(packageOrder.getPhone());
|
|
|
- logs.setSendTime(new Date());
|
|
|
- logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- logs.setMid(itemVO.getMid());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
- logs.setNumber(counts);
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }else if (sms.getType().equals("dh")){
|
|
|
- SendSmsReturn sendSmsReturn =null;
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- sendSmsReturn = smsTService.sendSms(sms.getDhAccount1(), sms.getDhPassword1(), content, packageOrder.getPhone());
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- sendSmsReturn= smsTService.sendSms(sms.getDhAccount2(),sms.getDhPassword2(),content+"拒收请回复R", packageOrder.getPhone());
|
|
|
- }
|
|
|
- System.out.println(sendSmsReturn);
|
|
|
- if (sendSmsReturn!=null){
|
|
|
- if (sendSmsReturn.getResult()!=null&&sendSmsReturn.getResult().equals("0")){
|
|
|
- CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
- logs.setCompanyId(param.getCompanyId());
|
|
|
- logs.setContent(content);
|
|
|
- logs.setTempCode(temp.getTempCode());
|
|
|
- logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
- logs.setTempId(temp.getTempId());
|
|
|
- logs.setPhone(packageOrder.getPhone());
|
|
|
- logs.setSendTime(new Date());
|
|
|
- logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- logs.setMid(sendSmsReturn.getMsgid());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
- logs.setNumber(counts);
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
- }
|
|
|
- }
|
|
|
+ // ===== 动态路由发送 =====
|
|
|
+ String sendResult = resolveAndSend(packageOrder.getPhone(), content, temp.getTempType(),
|
|
|
+ param.getCompanyId(), param.getCompanyUserId(), null);
|
|
|
+ if ("OK".equals(sendResult)) {
|
|
|
+ CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
+ logs.setCompanyId(param.getCompanyId());
|
|
|
+ logs.setContent(content);
|
|
|
+ logs.setTempCode(temp.getTempCode());
|
|
|
+ logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
+ logs.setTempId(temp.getTempId());
|
|
|
+ logs.setPhone(packageOrder.getPhone());
|
|
|
+ logs.setSendTime(new Date());
|
|
|
+ logs.setStatus(0);
|
|
|
+ Integer counts = content.length()/67;
|
|
|
+ if(content.length()%67>0) counts++;
|
|
|
+ if(counts==0) counts=1;
|
|
|
+ logs.setNumber(counts);
|
|
|
+ smsLogsService.insertCompanySmsLogs(logs);
|
|
|
+ companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
}
|
|
|
return R.ok("短信提交成功,正在发送中...");
|
|
|
}
|
|
|
@@ -566,6 +666,8 @@ public class SmsServiceImpl implements ISmsService
|
|
|
content = content.replace("${sms.captcha}", captcha);
|
|
|
}
|
|
|
String urls = null;
|
|
|
+ // sendCaptcha为验证码发送(系统级,无companyId), 回退到全局配置
|
|
|
+ // TODO: 后续可传入companyId后调用resolveAndSend
|
|
|
SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.sms");
|
|
|
FsSmsConfig sms = JSON.parseObject(sysConfig.getConfigValue(), FsSmsConfig.class);
|
|
|
if (sms.getType().equals("rf")) {
|
|
|
@@ -679,58 +781,12 @@ public class SmsServiceImpl implements ISmsService
|
|
|
content=content.replace("${sms.cardUrl}",param.getCardUrl());
|
|
|
}
|
|
|
|
|
|
- String urls= null;
|
|
|
- // 通知类的不加 退订回T 只有营销类的加
|
|
|
- //最多500个手机号
|
|
|
- SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.sms");
|
|
|
- FsSmsConfig sms = JSON.parseObject(sysConfig.getConfigValue(), FsSmsConfig.class);
|
|
|
- if (sms.getType().equals("rf")){
|
|
|
- try {
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- urls = sms.getRfUrl1()+"sms?action=send&account="+sms.getRfAccount1()+"&password="+sms.getRfPassword1()+"&mobile="+crmCustomer.getMobile()+"&content="+ URLEncoder.encode(sms.getRfSign()+content, "UTF-8")+"&extno="+sms.getRfCode1()+"&rt=json";
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- urls = sms.getRfUrl2()+"sms?action=send&account="+sms.getRfAccount2()+"&password="+sms.getRfPassword2()+"&mobile="+crmCustomer.getMobile()+"&content="+ URLEncoder.encode(sms.getRfSign()+content+"拒收请回复R", "UTF-8")+"&extno="+sms.getRfCode2()+"&rt=json";
|
|
|
- }
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- String post = HttpRequest.get(urls)
|
|
|
-// .body(String.valueOf(jsonObject))
|
|
|
- .execute().body();
|
|
|
- SmsSendVO vo=JSONUtil.toBean(post, SmsSendVO.class);
|
|
|
- if(vo.getStatus().equals(0)){
|
|
|
- Integer resultCount=0;
|
|
|
- for(SmsSendItemVO itemVO:vo.getList()){
|
|
|
- if(itemVO.getResult().equals("0")){
|
|
|
- CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
- logs.setCompanyId(param.getCompanyId());
|
|
|
- logs.setCustomerId(id);
|
|
|
- logs.setContent(content);
|
|
|
- logs.setTempCode(temp.getTempCode());
|
|
|
- logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
- logs.setTempId(temp.getTempId());
|
|
|
- logs.setPhone(crmCustomer.getMobile());
|
|
|
- logs.setSendTime(new Date());
|
|
|
- logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- logs.setMid(itemVO.getMid());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
- logs.setNumber(counts);
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
- resultCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }else if (sms.getType().equals("dh")){
|
|
|
- SendSmsReturn sendSmsReturn =null;
|
|
|
+ // ===== 动态路由发送 =====
|
|
|
+ Long preferApiId = null; // TODO: 从param中获取销售手动选择的接口ID
|
|
|
+ String sendResult = resolveAndSend(crmCustomer.getMobile(), content, temp.getTempType(),
|
|
|
+ param.getCompanyId(), param.getCompanyUserId(), preferApiId);
|
|
|
+
|
|
|
+ if ("OK".equals(sendResult)) {
|
|
|
CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
logs.setCompanyId(param.getCompanyId());
|
|
|
logs.setCustomerId(id);
|
|
|
@@ -741,34 +797,15 @@ public class SmsServiceImpl implements ISmsService
|
|
|
logs.setPhone(crmCustomer.getMobile());
|
|
|
logs.setSendTime(new Date());
|
|
|
logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
+ Integer counts = content.length()/67;
|
|
|
+ if(content.length()%67>0) counts++;
|
|
|
+ if(counts==0) counts=1;
|
|
|
logs.setNumber(counts);
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- sendSmsReturn = smsTService.sendSms(sms.getDhAccount1(), sms.getDhPassword1(), content, crmCustomer.getMobile());
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- sendSmsReturn= smsTService.sendSms(sms.getDhAccount2(),sms.getDhPassword2(),content+"拒收请回复R",crmCustomer.getMobile());
|
|
|
- }
|
|
|
- System.out.println(sendSmsReturn);
|
|
|
- if (sendSmsReturn!=null){
|
|
|
- if (sendSmsReturn.getResult()!=null&&sendSmsReturn.getResult().equals("0")){
|
|
|
- logs.setMid(sendSmsReturn.getMsgid());
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
- }
|
|
|
- }
|
|
|
+ smsLogsService.insertCompanySmsLogs(logs);
|
|
|
+ companySmsService.subCompanySms(logs.getCompanyId(),logs.getNumber());
|
|
|
+ } else {
|
|
|
+ log.warn("batchSmsOp: 发送失败 phone={}, result={}", crmCustomer.getMobile(), sendResult);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -799,68 +836,11 @@ public class SmsServiceImpl implements ISmsService
|
|
|
content=content.replace("${sms.senderName}",param.getSenderName());
|
|
|
}
|
|
|
|
|
|
- String urls= null;
|
|
|
- // 通知类的不加 退订回T 只有营销类的加
|
|
|
- //最多500个手机号
|
|
|
- SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.sms");
|
|
|
- FsSmsConfig sms = JSON.parseObject(sysConfig.getConfigValue(), FsSmsConfig.class);
|
|
|
- if (sms.getType().equals("rf")){
|
|
|
- try {
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- urls = sms.getRfUrl1()+"sms?action=send&account="+sms.getRfAccount1()+"&password="+sms.getRfPassword1()+"&mobile="+crmCustomer.getMobile()+"&content="+ URLEncoder.encode(sms.getRfSign()+content, "UTF-8")+"&extno="+sms.getRfCode1()+"&rt=json";
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- urls = sms.getRfUrl2()+"sms?action=send&account="+sms.getRfAccount2()+"&password="+sms.getRfPassword2()+"&mobile="+crmCustomer.getMobile()+"&content="+ URLEncoder.encode(sms.getRfSign()+content+"拒收请回复R", "UTF-8")+"&extno="+sms.getRfCode2()+"&rt=json";
|
|
|
- }
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- String post = HttpRequest.get(urls)
|
|
|
-// .body(String.valueOf(jsonObject))
|
|
|
- .execute().body();
|
|
|
- SmsSendVO vo=JSONUtil.toBean(post, SmsSendVO.class);
|
|
|
- if(vo.getStatus().equals(0)){
|
|
|
- Integer resultCount=0;
|
|
|
- for(SmsSendItemVO itemVO:vo.getList()){
|
|
|
- if(itemVO.getResult().equals("0")){
|
|
|
- CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
- logs.setCompanyId(param.getCompanyId());
|
|
|
- logs.setCustomerId(id);
|
|
|
- logs.setContent(content);
|
|
|
- logs.setTempCode(temp.getTempCode());
|
|
|
- logs.setCompanyUserId(param.getCompanyUserId());
|
|
|
- logs.setTempId(temp.getTempId());
|
|
|
- logs.setPhone(crmCustomer.getMobile());
|
|
|
- logs.setSendTime(new Date());
|
|
|
- logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- logs.setMid(itemVO.getMid());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
- logs.setNumber(counts);
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- // 使用Redisson分布式锁,按公司ID级别锁定,确保集群环境下扣减准确
|
|
|
- String lockKey = SMS_SUB_LOCK_PREFIX + logs.getCompanyId();
|
|
|
- RLock lock = redissonClient.getLock(lockKey);
|
|
|
- try {
|
|
|
- lock.lock(30, TimeUnit.SECONDS);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(), logs.getNumber());
|
|
|
- } finally {
|
|
|
- if (lock.isHeldByCurrentThread()) {
|
|
|
- lock.unlock();
|
|
|
- }
|
|
|
- }
|
|
|
- resultCount++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }else if (sms.getType().equals("dh")){
|
|
|
- SendSmsReturn sendSmsReturn =null;
|
|
|
+ // ===== 动态路由发送 =====
|
|
|
+ String sendResult = resolveAndSend(crmCustomer.getMobile(), content, temp.getTempType(),
|
|
|
+ param.getCompanyId(), param.getCompanyUserId(), null);
|
|
|
+
|
|
|
+ if ("OK".equals(sendResult)) {
|
|
|
CompanySmsLogs logs=new CompanySmsLogs();
|
|
|
logs.setCompanyId(param.getCompanyId());
|
|
|
logs.setCustomerId(id);
|
|
|
@@ -871,39 +851,24 @@ public class SmsServiceImpl implements ISmsService
|
|
|
logs.setPhone(crmCustomer.getMobile());
|
|
|
logs.setSendTime(new Date());
|
|
|
logs.setStatus(0);
|
|
|
- logs.setType(sms.getType());
|
|
|
- Integer counts=logs.getContent().length()/67;
|
|
|
- if(logs.getContent().length()%67>0){
|
|
|
- counts=counts+1;
|
|
|
- }
|
|
|
- if(counts==0){
|
|
|
- counts=1;
|
|
|
- }
|
|
|
+ Integer counts = content.length()/67;
|
|
|
+ if(content.length()%67>0) counts++;
|
|
|
+ if(counts==0) counts=1;
|
|
|
logs.setNumber(counts);
|
|
|
- if(temp.getTempType().equals(1)){
|
|
|
- sendSmsReturn = smsTService.sendSms(sms.getDhAccount1(), sms.getDhPassword1(), content, crmCustomer.getMobile());
|
|
|
- }
|
|
|
- else if(temp.getTempType().equals(2)){
|
|
|
- sendSmsReturn= smsTService.sendSms(sms.getDhAccount2(),sms.getDhPassword2(),content+"拒收请回复R",crmCustomer.getMobile());
|
|
|
- }
|
|
|
- System.out.println(sendSmsReturn);
|
|
|
- if (sendSmsReturn!=null){
|
|
|
- if (sendSmsReturn.getResult()!=null&&sendSmsReturn.getResult().equals("0")){
|
|
|
- logs.setMid(sendSmsReturn.getMsgid());
|
|
|
- smsLogsService.insertCompanySmsLogs(logs);
|
|
|
- // 使用Redisson分布式锁,按公司ID级别锁定,确保集群环境下扣减准确
|
|
|
- String lockKey = SMS_SUB_LOCK_PREFIX + logs.getCompanyId();
|
|
|
- RLock lock = redissonClient.getLock(lockKey);
|
|
|
- try {
|
|
|
- lock.lock(30, TimeUnit.SECONDS);
|
|
|
- companySmsService.subCompanySms(logs.getCompanyId(), logs.getNumber());
|
|
|
- } finally {
|
|
|
- if (lock.isHeldByCurrentThread()) {
|
|
|
- lock.unlock();
|
|
|
- }
|
|
|
- }
|
|
|
+ smsLogsService.insertCompanySmsLogs(logs);
|
|
|
+ // 使用Redisson分布式锁
|
|
|
+ String lockKey = SMS_SUB_LOCK_PREFIX + logs.getCompanyId();
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+ try {
|
|
|
+ lock.lock(30, TimeUnit.SECONDS);
|
|
|
+ companySmsService.subCompanySms(logs.getCompanyId(), logs.getNumber());
|
|
|
+ } finally {
|
|
|
+ if (lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
}
|
|
|
}
|
|
|
+ } else {
|
|
|
+ log.warn("batchSmsOp4AiSend: 发送失败 phone={}, result={}", crmCustomer.getMobile(), sendResult);
|
|
|
}
|
|
|
}
|
|
|
}
|