@@ -19,7 +19,6 @@ import com.ningdatech.basic.exception.BizException; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.stereotype.Component; | |||
import org.springframework.web.servlet.View; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
@@ -43,7 +42,6 @@ import static com.hz.pm.api.sys.model.entity.MsgCallRecord.SendStatus; | |||
public class MsgCallHelper { | |||
private final IMsgCallRecordService msgCallRecordService; | |||
private final View error; | |||
/** | |||
* 发送短信 | |||
@@ -136,8 +134,8 @@ public class MsgCallHelper { | |||
} | |||
}); | |||
CallRetDTO<SendCallDTO> ret = MobileCallClient.getClient().sendCall(phones, content); | |||
log.info("电话拨打:{} {}", phones, ret); | |||
if (!ret.isOk()) { | |||
log.error("电话拨打失败:{}", ret); | |||
throw BizException.wrap("电话拨打失败"); | |||
} | |||
SendCallDTO data = ret.getData(); | |||
@@ -170,6 +168,7 @@ public class MsgCallHelper { | |||
public List<ReplyCallDTO> callReply(String submitKey) { | |||
CallRetDTO<List<ReplyCallDTO>> retCallReplies = MobileCallClient.getClient().replyCall(submitKey); | |||
log.error("获取电话回执:{} {}", submitKey, retCallReplies); | |||
if (retCallReplies.isOk()) { | |||
List<ReplyCallDTO> replies = retCallReplies.getData(); | |||
if (replies == null || replies.isEmpty()) { | |||
@@ -177,7 +176,6 @@ public class MsgCallHelper { | |||
} | |||
return replies; | |||
} | |||
log.error("获取电话回执失败:{} {}", submitKey, retCallReplies); | |||
throw BizException.wrap("获取电话回执失败"); | |||
} | |||
@@ -36,12 +36,31 @@ public class MobileCallClient { | |||
@Data | |||
public static class ReplyCallDTO { | |||
private Integer duration; | |||
private String remark; | |||
private Integer dialStatus; | |||
private String remoteNumber; | |||
private String dtmf; | |||
/** | |||
* 提交时间 | |||
*/ | |||
private Date sendDate; | |||
/** | |||
* 接通时间 | |||
*/ | |||
private Date answerDate; | |||
/** | |||
* 拨号时间 | |||
*/ | |||
private Date dialDate; | |||
} | |||
//================================================================================================================== | |||
@@ -0,0 +1,64 @@ | |||
package com.hz.pm.api.external.model.enumeration; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Getter; | |||
import java.util.Arrays; | |||
import java.util.Optional; | |||
/** | |||
* <p> | |||
* CallDialStatus | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 10:27 2024/4/30 | |||
*/ | |||
@Getter | |||
@AllArgsConstructor | |||
public enum CallDialStatus { | |||
/** | |||
* 未拨号 | |||
*/ | |||
NOT_DIALED(0, "未拨号"), | |||
/** | |||
* 拨号中 | |||
*/ | |||
DIALING(1, "拨号中"), | |||
/** | |||
* 通话中 | |||
*/ | |||
IN_CALL(2, "通话中"), | |||
/** | |||
* 通话结束(已接通) | |||
*/ | |||
CALL_ENDED_CONNECTED(3, "通话结束(已接通)"), | |||
/** | |||
* 通话结束(未接通) | |||
*/ | |||
CALL_ENDED_DISCONNECTED(4, "通话结束(未接通)"); | |||
private final Integer status; | |||
private final String remark; | |||
/** | |||
* 根据整型值获取对应的DialStatus枚举 | |||
* | |||
* @param status 整型状态值 | |||
* @return 对应的DialStatus枚举,如果状态值不匹配则返回null | |||
*/ | |||
public static Optional<CallDialStatus> get(Integer status) { | |||
return Arrays.stream(values()).filter(w -> w.getStatus().equals(status)).findFirst(); | |||
} | |||
public static CallDialStatus getNoNull(Integer status) { | |||
return get(status).orElseThrow(() -> new IllegalArgumentException("无效的拨号状态")); | |||
} | |||
} |
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.hz.pm.api.common.helper.MsgCallHelper; | |||
import com.hz.pm.api.common.util.BizUtils; | |||
import com.hz.pm.api.common.util.MDCThreadPoolTaskExecutor; | |||
import com.hz.pm.api.external.model.enumeration.CallDialStatus; | |||
import com.hz.pm.api.external.sms.vo.SmsReply; | |||
import com.hz.pm.api.external.sms.vo.SmsReplyDTO; | |||
import com.hz.pm.api.sys.model.entity.MsgCallRecord; | |||
@@ -68,7 +69,7 @@ public class MsgCallReplyRewriteTask { | |||
} | |||
@Scheduled(fixedRateString = "${msg-call-reply-write.fixed-rate:2}", timeUnit = TimeUnit.MINUTES) | |||
@Scheduled(fixedRateString = "${msg-call-reply-write.fixed-rate:1}", timeUnit = TimeUnit.MINUTES) | |||
public void replyRewrite() { | |||
log.info("开始获取短信电话回执"); | |||
Wrapper<MsgCallRecord> query = Wrappers.lambdaQuery(MsgCallRecord.class) | |||
@@ -153,10 +154,28 @@ public class MsgCallReplyRewriteTask { | |||
List<MsgCallRecord> updates = new ArrayList<>(); | |||
for (MsgCallRecord w : recordsBySubmitKey) { | |||
ReplyCallDTO reply = replyMap.get(w.getReceivePhone()); | |||
if (reply != null) { | |||
w.setReplyOn(LocalDateTimeUtil.of(reply.getSendDate())); | |||
w.setReplyContent(reply.getDtmf()); | |||
w.setReplyStatus(ReplyStatus.SUCCESS); | |||
if (reply == null) { | |||
continue; | |||
} | |||
switch (CallDialStatus.getNoNull(reply.getDialStatus())) { | |||
case DIALING: | |||
case IN_CALL: | |||
case NOT_DIALED: | |||
break; | |||
case CALL_ENDED_CONNECTED: | |||
w.setReplyStatus(ReplyStatus.SUCCESS); | |||
w.setReplyContent(reply.getDtmf()); | |||
w.setReplyOn(LocalDateTimeUtil.of(reply.getAnswerDate())); | |||
w.setDuration(reply.getDuration()); | |||
break; | |||
case CALL_ENDED_DISCONNECTED: | |||
w.setReplyStatus(ReplyStatus.FAILED); | |||
w.setReplyOn(LocalDateTimeUtil.of(reply.getDialDate())); | |||
w.setReplyContent(reply.getDtmf()); | |||
w.setErrorRemark(reply.getRemark()); | |||
break; | |||
} | |||
if (!ReplyStatus.WAITING.equals(w.getReplyStatus())) { | |||
updates.add(w); | |||
} | |||
} | |||
@@ -90,6 +90,16 @@ public class MsgCallRecord implements Serializable { | |||
private String replyContent; | |||
/** | |||
* 失败原因 | |||
*/ | |||
private String errorRemark; | |||
/** | |||
* 语音时长 | |||
*/ | |||
private Integer duration; | |||
/** | |||
* 回复时间 | |||
*/ | |||
private LocalDateTime replyOn; | |||
@@ -197,6 +197,9 @@ agent-login: | |||
sms-send: | |||
host: http://10.54.38.13:8081/mh-gateway/auth-single | |||
mobile-call: | |||
host: http://115.194.186.131:18181/blue_esl_api | |||
# 提醒任务 | |||
reminder-task: | |||
declared-record: | |||
@@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.core.env.Environment; | |||
import java.util.Arrays; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
@@ -27,16 +28,29 @@ class MobileCallClientTest extends AppTests { | |||
@Autowired | |||
private MsgCallHelper msgCallHelper; | |||
String[] phoneNumbers = { | |||
"19957013396", // 李尧 | |||
// "18054175326", // 赵轩敏 | |||
"15381275208", // 张轩晨 | |||
"13588706094", // 邱大山 | |||
"18157330337", // 章侦干 | |||
// "18158711166", // 朱小青 | |||
// "13034219881", // 吴敏 | |||
"15305711225", // 马巍 | |||
"17364572214" // 纪泽兵 | |||
}; | |||
@Test | |||
void sendCall() { | |||
String format = String.format("尊敬的专家您好,%s现邀请您作为专家参加%s会议,会议时间:%s,会议地点:%s。 确认参加请按 1,拒绝参加请按 2。请您选择,重听请按星号键。", | |||
"信创办", "测试语音", "2024年1月1日 12:30", "杭州市"); | |||
String ret = msgCallHelper.sendCall("17364572214", format, BizTypeEnum.EXPERT_INVITE); | |||
"杭州市信创办", "测试智能外呼", "2024年1月1日 12:30", "杭州市上城区市民中心"); | |||
//String ret = msgCallHelper.sendCall("17364572214", format, BizTypeEnum.EXPERT_INVITE); | |||
String ret = msgCallHelper.sendCall(Arrays.asList(phoneNumbers), format, BizTypeEnum.EXPERT_INVITE); | |||
System.out.println(ret); | |||
} | |||
@Test | |||
void replyCall() { | |||
System.out.println(msgCallHelper.callReply("3086839870409281536")); | |||
System.out.println(msgCallHelper.callReply("3087578611042095104")); | |||
} | |||
} |
@@ -196,4 +196,4 @@ agent-login: | |||
sms-send: | |||
host: http://10.54.38.13:8081/mh-gateway/auth-single | |||
mobile-call: | |||
host: http://36.20.16.36:18181/blue_esl_api | |||
host: http://115.194.186.131:18181/blue_esl_api |