post cdr
This commit is contained in:
parent
33e026a92d
commit
3ef8fc4799
@ -21,6 +21,7 @@ import com.pudonghot.yo.mapper.CallRecordingMapper;
|
|||||||
import com.pudonghot.yo.cms.model.HangupCauseMapping;
|
import com.pudonghot.yo.cms.model.HangupCauseMapping;
|
||||||
import com.pudonghot.yo.model.domain.CallDetailRecord;
|
import com.pudonghot.yo.model.domain.CallDetailRecord;
|
||||||
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordAll;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import com.pudonghot.yo.cms.form.FormListCallDetailRecord;
|
import com.pudonghot.yo.cms.form.FormListCallDetailRecord;
|
||||||
import com.wacai.tigon.web.controller.BaseQueryController;
|
import com.wacai.tigon.web.controller.BaseQueryController;
|
||||||
@ -51,7 +52,7 @@ filterCols = {
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RequestMapping("/cms/api/call-detail-record")
|
@RequestMapping("/cms/api/call-detail-record")
|
||||||
public class CallDetailRecordController
|
public class CallDetailRecordController
|
||||||
extends BaseQueryController<Integer, CallDetailRecord, FormListCallDetailRecord>
|
extends BaseQueryController<Integer, CallDetailRecordAll, FormListCallDetailRecord>
|
||||||
implements SessionAbility {
|
implements SessionAbility {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -2,8 +2,8 @@ package com.pudonghot.yo.cms.service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.wacai.tigon.service.BaseQueryService;
|
import com.wacai.tigon.service.BaseQueryService;
|
||||||
import com.pudonghot.yo.model.domain.CallDetailRecord;
|
|
||||||
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordAll;
|
||||||
import com.pudonghot.yo.model.request.ReqCallDetailRecordAccountReport;
|
import com.pudonghot.yo.model.request.ReqCallDetailRecordAccountReport;
|
||||||
import com.pudonghot.yo.cms.service.request.CallDetailRecordDeleteServReq;
|
import com.pudonghot.yo.cms.service.request.CallDetailRecordDeleteServReq;
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ import com.pudonghot.yo.cms.service.request.CallDetailRecordDeleteServReq;
|
|||||||
* @author Donghuang
|
* @author Donghuang
|
||||||
* @date Oct 21, 2020 21:10:19
|
* @date Oct 21, 2020 21:10:19
|
||||||
*/
|
*/
|
||||||
public interface CallDetailRecordService extends BaseQueryService<Integer, CallDetailRecord> {
|
public interface CallDetailRecordService extends BaseQueryService<Integer, CallDetailRecordAll> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* account report
|
* account report
|
||||||
|
@ -13,9 +13,9 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.pudonghot.yo.mapper.CallRecordingMapper;
|
import com.pudonghot.yo.mapper.CallRecordingMapper;
|
||||||
import com.pudonghot.yo.model.domain.CallRecording;
|
import com.pudonghot.yo.model.domain.CallRecording;
|
||||||
import com.pudonghot.yo.model.domain.CallDetailRecord;
|
|
||||||
import com.pudonghot.yo.mapper.CallDetailRecordMapper;
|
|
||||||
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
||||||
|
import com.pudonghot.yo.mapper.CallDetailRecordAllMapper;
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordAll;
|
||||||
import com.pudonghot.yo.cms.service.CallDetailRecordService;
|
import com.pudonghot.yo.cms.service.CallDetailRecordService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import com.wacai.tigon.service.support.BaseQueryServiceSupport;
|
import com.wacai.tigon.service.support.BaseQueryServiceSupport;
|
||||||
@ -29,8 +29,8 @@ import com.pudonghot.yo.cms.service.request.CallDetailRecordDeleteServReq;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class CallDetailRecordServiceImpl
|
public class CallDetailRecordServiceImpl
|
||||||
extends BaseQueryServiceSupport<Integer, CallDetailRecord, CallDetailRecordMapper>
|
extends BaseQueryServiceSupport<Integer, CallDetailRecordAll, CallDetailRecordAllMapper>
|
||||||
implements CallDetailRecordService{
|
implements CallDetailRecordService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CallRecordingMapper recordingMapper;
|
private CallRecordingMapper recordingMapper;
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.pudonghot.yo.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import me.chyxion.tigon.mybatis.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordAll;
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordBase;
|
||||||
|
import com.pudonghot.yo.model.request.ReqCallDetailRecordAccountReport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date Sep 09, 2021 01:06:07
|
||||||
|
*/
|
||||||
|
public interface CallDetailRecordAllMapper extends BaseMapper<Integer, CallDetailRecordAll> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert base model
|
||||||
|
*
|
||||||
|
* @param model model
|
||||||
|
* @return insert row
|
||||||
|
*/
|
||||||
|
int insert(@Param(PARAM_MODEL_KEY) CallDetailRecordBase model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* account report
|
||||||
|
*
|
||||||
|
* @param arg arg
|
||||||
|
* @return account report
|
||||||
|
*/
|
||||||
|
List<CallDetailReport> accountReport(
|
||||||
|
@Param("arg") ReqCallDetailRecordAccountReport arg);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?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">
|
||||||
|
<!--
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date Sep 09, 2021 01:06:00
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<mapper namespace="com.pudonghot.yo.mapper.CallDetailRecordAllMapper">
|
||||||
|
|
||||||
|
<select id="accountReport" resultType="com.pudonghot.yo.model.dbobject.CallDetailReport">
|
||||||
|
select account,
|
||||||
|
dial_type,
|
||||||
|
call_type,
|
||||||
|
count(id) total,
|
||||||
|
count(answer_stamp) answered,
|
||||||
|
sec_to_time(sum(billsec)) duration,
|
||||||
|
sec_to_time(max(billsec)) max_duration,
|
||||||
|
sec_to_time(round(avg(billsec), 0)) avg_duration,
|
||||||
|
min(start_stamp) min_start_stamp,
|
||||||
|
max(start_stamp) max_start_stamp
|
||||||
|
from br_call_detail_record
|
||||||
|
where start_stamp between #{arg.dateFrom} and #{arg.dateTo}
|
||||||
|
<if test="arg.account != null">
|
||||||
|
and account = #{arg.account}
|
||||||
|
</if>
|
||||||
|
and tenant_id = #{arg.tenantId}
|
||||||
|
group by account, dial_type, call_type
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
@ -1,14 +1,10 @@
|
|||||||
package com.pudonghot.yo.mapper;
|
package com.pudonghot.yo.mapper;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import lombok.val;
|
|
||||||
import me.chyxion.tigon.mybatis.BaseMapper;
|
|
||||||
import me.chyxion.tigon.mybatis.Search;
|
import me.chyxion.tigon.mybatis.Search;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import me.chyxion.tigon.mybatis.BaseMapper;
|
||||||
import com.pudonghot.yo.model.domain.CallDetailRecord;
|
import com.pudonghot.yo.model.domain.CallDetailRecord;
|
||||||
import com.pudonghot.yo.model.dbobject.CallDetailReport;
|
import com.pudonghot.yo.model.domain.CallDetailRecordBase;
|
||||||
import com.pudonghot.yo.model.request.ReqCallDetailRecordAccountReport;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Donghuang <br>
|
* @author Donghuang <br>
|
||||||
@ -16,6 +12,14 @@ import com.pudonghot.yo.model.request.ReqCallDetailRecordAccountReport;
|
|||||||
*/
|
*/
|
||||||
public interface CallDetailRecordMapper extends BaseMapper<Integer, CallDetailRecord> {
|
public interface CallDetailRecordMapper extends BaseMapper<Integer, CallDetailRecord> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert base model
|
||||||
|
*
|
||||||
|
* @param model model
|
||||||
|
* @return insert row
|
||||||
|
*/
|
||||||
|
int insert(@Param(PARAM_MODEL_KEY) CallDetailRecordBase model);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 呼叫在灰名单中,有效
|
* 呼叫在灰名单中,有效
|
||||||
*
|
*
|
||||||
@ -27,14 +31,6 @@ public interface CallDetailRecordMapper extends BaseMapper<Integer, CallDetailRe
|
|||||||
@Param("tenantId") Integer tenantId,
|
@Param("tenantId") Integer tenantId,
|
||||||
@Param("calledNumber") String calledNumber);
|
@Param("calledNumber") String calledNumber);
|
||||||
|
|
||||||
/**
|
|
||||||
* account report
|
|
||||||
* @param arg arg
|
|
||||||
* @return account report
|
|
||||||
*/
|
|
||||||
List<CallDetailReport> accountReport(
|
|
||||||
@Param("arg") ReqCallDetailRecordAccountReport arg);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find by conn id
|
* find by conn id
|
||||||
*
|
*
|
||||||
|
@ -34,24 +34,4 @@
|
|||||||
) t
|
) t
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="accountReport" resultType="com.pudonghot.yo.model.dbobject.CallDetailReport">
|
|
||||||
select account,
|
|
||||||
dial_type,
|
|
||||||
call_type,
|
|
||||||
count(id) total,
|
|
||||||
count(answer_stamp) answered,
|
|
||||||
sec_to_time(sum(billsec)) duration,
|
|
||||||
sec_to_time(max(billsec)) max_duration,
|
|
||||||
sec_to_time(round(avg(billsec), 0)) avg_duration,
|
|
||||||
min(start_stamp) min_start_stamp,
|
|
||||||
max(start_stamp) max_start_stamp
|
|
||||||
from br_call_detail_record
|
|
||||||
where start_stamp between #{arg.dateFrom} and #{arg.dateTo}
|
|
||||||
<if test="arg.account != null">
|
|
||||||
and account = #{arg.account}
|
|
||||||
</if>
|
|
||||||
and tenant_id = #{arg.tenantId}
|
|
||||||
group by account, dial_type, call_type
|
|
||||||
</select>
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
@ -30,6 +30,8 @@ import java.util.Scanner;
|
|||||||
public class CallDetailRecordMapperTest {
|
public class CallDetailRecordMapperTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
private CallDetailRecordMapper mapper;
|
private CallDetailRecordMapper mapper;
|
||||||
|
@Autowired
|
||||||
|
private CallDetailRecordAllMapper allMapper;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testList() {
|
public void testList() {
|
||||||
@ -48,7 +50,7 @@ public class CallDetailRecordMapperTest {
|
|||||||
arg.setTenantId(1);
|
arg.setTenantId(1);
|
||||||
arg.setDateFrom(DateUtils.parseDate("2020-10-10", "yyyy-MM-dd"));
|
arg.setDateFrom(DateUtils.parseDate("2020-10-10", "yyyy-MM-dd"));
|
||||||
arg.setDateTo(DateUtils.parseDate("2020-10-11", "yyyy-MM-dd"));
|
arg.setDateTo(DateUtils.parseDate("2020-10-11", "yyyy-MM-dd"));
|
||||||
val result = mapper.accountReport(arg);
|
val result = allMapper.accountReport(arg);
|
||||||
log.info("List [{}].", result);
|
log.info("List [{}].", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ public class Agent extends TaggableDomain {
|
|||||||
private String queues;
|
private String queues;
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
|
SYSTEM,
|
||||||
PERSON,
|
PERSON,
|
||||||
ROBOT,
|
ROBOT,
|
||||||
IVR
|
IVR
|
||||||
|
@ -2,12 +2,7 @@ package com.pudonghot.yo.model.domain;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import java.util.Date;
|
|
||||||
import com.wacai.tigon.model.M0;
|
|
||||||
import me.chyxion.tigon.mybatis.Table;
|
import me.chyxion.tigon.mybatis.Table;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import me.chyxion.tigon.mybatis.NotUpdate;
|
|
||||||
import lombok.experimental.FieldNameConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Donghuang <br>
|
* @author Donghuang <br>
|
||||||
@ -16,88 +11,7 @@ import lombok.experimental.FieldNameConstants;
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@Table("br_call_detail_record")
|
@Table("br_call_detail_record")
|
||||||
@FieldNameConstants(prefix = "")
|
public class CallDetailRecord extends CallDetailRecordBase {
|
||||||
public class CallDetailRecord extends M0<Integer> {
|
private static final long serialVersionUID = 1L;
|
||||||
@NotUpdate
|
|
||||||
private Integer tenantId;
|
|
||||||
@NotUpdate
|
|
||||||
private String tenantCode;
|
|
||||||
@NotUpdate
|
|
||||||
private String account;
|
|
||||||
@NotUpdate
|
|
||||||
private String connId;
|
|
||||||
|
|
||||||
@NotUpdate
|
|
||||||
private DialType dialType;
|
|
||||||
@NotUpdate
|
|
||||||
private CallType callType;
|
|
||||||
@NotUpdate
|
|
||||||
private Agent.Type agentType;
|
|
||||||
@NotUpdate
|
|
||||||
private Integer campaignId;
|
|
||||||
@NotUpdate
|
|
||||||
private String caseKey;
|
|
||||||
|
|
||||||
@NotUpdate
|
|
||||||
private String uuid;
|
|
||||||
@NotUpdate
|
|
||||||
private String callUuid;
|
|
||||||
@NotUpdate
|
|
||||||
private String callerNumber;
|
|
||||||
@NotUpdate
|
|
||||||
private String calledNumber;
|
|
||||||
@NotUpdate
|
|
||||||
private Integer trunkId;
|
|
||||||
@NotUpdate
|
|
||||||
private String callingPartyNumber;
|
|
||||||
@NotUpdate
|
|
||||||
private Date startStamp;
|
|
||||||
@NotUpdate
|
|
||||||
private Date answerStamp;
|
|
||||||
@NotUpdate
|
|
||||||
private Date endStamp;
|
|
||||||
@NotUpdate
|
|
||||||
private Long duration;
|
|
||||||
@NotUpdate
|
|
||||||
private Long mduration;
|
|
||||||
@NotUpdate
|
|
||||||
private Long billsec;
|
|
||||||
@NotUpdate
|
|
||||||
private Long billmsec;
|
|
||||||
@NotUpdate
|
|
||||||
private String endpointDisposition;
|
|
||||||
@NotUpdate
|
|
||||||
private String hangupCause;
|
|
||||||
@NotUpdate
|
|
||||||
private String hangupDisposition;
|
|
||||||
private Boolean deleted;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public enum DialType {
|
|
||||||
MANUAL("手"),
|
|
||||||
INBOUND("进"),
|
|
||||||
CAMPAIGN("预");
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public enum CallDirection {
|
|
||||||
INCOMING("来电"),
|
|
||||||
OUTGOING("去电");
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public enum CallType {
|
|
||||||
INTERNAL("内线"),
|
|
||||||
INBOUND("进线"),
|
|
||||||
OUTBOUND("外呼");
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.pudonghot.yo.model.domain;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import me.chyxion.tigon.mybatis.Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang <br>
|
||||||
|
* Nov 14, 2019 11:32:42
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Table("br_call_detail_record_all")
|
||||||
|
public class CallDetailRecordAll extends CallDetailRecordBase {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
package com.pudonghot.yo.model.domain;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import java.util.Date;
|
||||||
|
import com.wacai.tigon.model.M0;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import me.chyxion.tigon.mybatis.NotUpdate;
|
||||||
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date Sep 09, 2021 22:47:13
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@FieldNameConstants(prefix = "")
|
||||||
|
public class CallDetailRecordBase extends M0<Integer> {
|
||||||
|
@NotUpdate
|
||||||
|
private Integer tenantId;
|
||||||
|
@NotUpdate
|
||||||
|
private String tenantCode;
|
||||||
|
@NotUpdate
|
||||||
|
private String account;
|
||||||
|
@NotUpdate
|
||||||
|
private String connId;
|
||||||
|
|
||||||
|
@NotUpdate
|
||||||
|
private DialType dialType;
|
||||||
|
@NotUpdate
|
||||||
|
private CallType callType;
|
||||||
|
@NotUpdate
|
||||||
|
private Agent.Type agentType;
|
||||||
|
@NotUpdate
|
||||||
|
private Integer campaignId;
|
||||||
|
@NotUpdate
|
||||||
|
private String caseKey;
|
||||||
|
|
||||||
|
@NotUpdate
|
||||||
|
private String uuid;
|
||||||
|
@NotUpdate
|
||||||
|
private String callUuid;
|
||||||
|
@NotUpdate
|
||||||
|
private String callerNumber;
|
||||||
|
@NotUpdate
|
||||||
|
private String calledNumber;
|
||||||
|
@NotUpdate
|
||||||
|
private Integer trunkId;
|
||||||
|
@NotUpdate
|
||||||
|
private String callingPartyNumber;
|
||||||
|
@NotUpdate
|
||||||
|
private Date startStamp;
|
||||||
|
@NotUpdate
|
||||||
|
private Date answerStamp;
|
||||||
|
@NotUpdate
|
||||||
|
private Date endStamp;
|
||||||
|
@NotUpdate
|
||||||
|
private Long duration;
|
||||||
|
@NotUpdate
|
||||||
|
private Long mduration;
|
||||||
|
@NotUpdate
|
||||||
|
private Long billsec;
|
||||||
|
@NotUpdate
|
||||||
|
private Long billmsec;
|
||||||
|
@NotUpdate
|
||||||
|
private String endpointDisposition;
|
||||||
|
@NotUpdate
|
||||||
|
private String hangupCause;
|
||||||
|
@NotUpdate
|
||||||
|
private String hangupDisposition;
|
||||||
|
private Boolean deleted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void beforeInsert() {
|
||||||
|
if (agentType == null) {
|
||||||
|
if ("SYSTEM".equals(account)) {
|
||||||
|
agentType = Agent.Type.SYSTEM;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
agentType = Agent.Type.PERSON;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deleted == null) {
|
||||||
|
deleted = Boolean.FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum DialType {
|
||||||
|
MANUAL("手"),
|
||||||
|
INBOUND("进"),
|
||||||
|
CAMPAIGN("预");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum CallDirection {
|
||||||
|
INCOMING("来电"),
|
||||||
|
OUTGOING("去电");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum CallType {
|
||||||
|
INTERNAL("内线"),
|
||||||
|
INBOUND("进线"),
|
||||||
|
OUTBOUND("外呼");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String text;
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,15 @@
|
|||||||
package com.pudonghot.yo.fsagent.controller;
|
package com.pudonghot.yo.fsagent.controller;
|
||||||
|
|
||||||
import java.util.Map;
|
import lombok.*;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordBase;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import com.pudonghot.yo.fsagent.service.CallDetailRecordService;
|
||||||
|
import com.pudonghot.yo.fsagent.controller.request.CdrCtrlrReqDTO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Donghuang <br>
|
* @author Donghuang <br>
|
||||||
@ -14,10 +19,38 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||||||
@Controller
|
@Controller
|
||||||
public class PostCdrController {
|
public class PostCdrController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CallDetailRecordService callDetailRecordService;
|
||||||
|
|
||||||
@PostMapping("/fsa/api/cdr/post")
|
@PostMapping("/fsa/api/cdr/post")
|
||||||
public void postCdr(
|
public void postCdr(@RequestParam("cdr") final String cdr) {
|
||||||
@RequestParam
|
log.info("Post cdr params: {}", cdr);
|
||||||
final Map<String, String> params) {
|
val cdrDTO = readObj(cdr);
|
||||||
log.info("Post cdr params: {}", params);
|
|
||||||
|
if (Boolean.TRUE.equals(cdrDTO.getIgnore())) {
|
||||||
|
log.debug("CDR ignored.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callDetailRecordService.insert(convert(cdrDTO, CallDetailRecordBase.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private CdrCtrlrReqDTO readObj(final String strCdr) {
|
||||||
|
val jsonNode = objectMapper.readTree(strCdr);
|
||||||
|
log.info("Json Node [{}].", jsonNode);
|
||||||
|
val dto = objectMapper.treeToValue(
|
||||||
|
jsonNode.get("variables"), CdrCtrlrReqDTO.class);
|
||||||
|
|
||||||
|
log.debug("CDR DTO [{}] read.", dto);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T convert(final Object obj, final Class<T> type) {
|
||||||
|
log.debug("Convert object [{}] to [{}].", obj, type);
|
||||||
|
return objectMapper.convertValue(obj, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.pudonghot.yo.fsagent.controller.request;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.ToString;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import org.codehaus.jackson.schema.JsonSerializableSchema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date Sep 08, 2021 10:50:55
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@JsonSerializableSchema
|
||||||
|
public class CdrCtrlrReqDTO implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@JsonAlias("odbc-cdr-ignore-leg")
|
||||||
|
private Boolean ignore;
|
||||||
|
@JsonAlias("x_tenant_id")
|
||||||
|
private Integer tenantId;
|
||||||
|
@JsonAlias("x_tenant_code")
|
||||||
|
private String tenantCode;
|
||||||
|
@JsonAlias("x_account")
|
||||||
|
private String account;
|
||||||
|
@JsonAlias("x_conn_id")
|
||||||
|
private String connId;
|
||||||
|
@JsonAlias("x_dial_type")
|
||||||
|
private String dialType;
|
||||||
|
@JsonAlias("x_call_type")
|
||||||
|
private String callType;
|
||||||
|
@JsonAlias("x_agent_type")
|
||||||
|
private String agentType;
|
||||||
|
@JsonAlias("x_campaign_id")
|
||||||
|
private Integer campaignId;
|
||||||
|
@JsonAlias("x_case_key")
|
||||||
|
private String caseKey;
|
||||||
|
|
||||||
|
private String uuid;
|
||||||
|
@JsonAlias("call_uuid")
|
||||||
|
private String callUuid;
|
||||||
|
@JsonAlias("sip_call_id")
|
||||||
|
private String sipCallId;
|
||||||
|
@JsonAlias({"caller_id_number", "sip_from_user"})
|
||||||
|
private String callerNumber;
|
||||||
|
@JsonAlias("x_called_number")
|
||||||
|
private String calledNumber;
|
||||||
|
@JsonAlias("x_trunk_id")
|
||||||
|
private Integer trunkId;
|
||||||
|
@JsonAlias("x_cpn")
|
||||||
|
private String callingPartyNumber;
|
||||||
|
@JsonAlias("start_stamp")
|
||||||
|
@Getter(onMethod_ = @JsonFormat(shape = JsonFormat.Shape.NUMBER))
|
||||||
|
@Setter(onMethod_ = @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss"))
|
||||||
|
private Date startStamp;
|
||||||
|
@JsonAlias("answer_stamp")
|
||||||
|
@Getter(onMethod_ = @JsonFormat(shape = JsonFormat.Shape.NUMBER))
|
||||||
|
@Setter(onMethod_ = @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss"))
|
||||||
|
private Date answerStamp;
|
||||||
|
@JsonAlias("end_stamp")
|
||||||
|
@Getter(onMethod_ = @JsonFormat(shape = JsonFormat.Shape.NUMBER))
|
||||||
|
@Setter(onMethod_ = @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss"))
|
||||||
|
private Date endStamp;
|
||||||
|
private Long duration;
|
||||||
|
private Long mduration;
|
||||||
|
private Long billsec;
|
||||||
|
private Long billmsec;
|
||||||
|
@JsonAlias("endpoint_disposition")
|
||||||
|
private String endpointDisposition;
|
||||||
|
@JsonAlias("hangup_cause")
|
||||||
|
private String hangupCause;
|
||||||
|
@JsonAlias("sip_hangup_disposition")
|
||||||
|
private String hangupDisposition;
|
||||||
|
}
|
@ -16,7 +16,7 @@ import org.freeswitch.esl.client.transport.event.Event;
|
|||||||
import com.pudonghot.yo.service.CommonAgentStatusService;
|
import com.pudonghot.yo.service.CommonAgentStatusService;
|
||||||
import com.pudonghot.yo.service.CommonAgentEventQueueService;
|
import com.pudonghot.yo.service.CommonAgentEventQueueService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import com.pudonghot.yo.model.domain.CallDetailRecord.DialType;
|
import com.pudonghot.yo.model.domain.CallDetailRecordBase.DialType;
|
||||||
import static com.pudonghot.yo.model.agentevent.EventType.AgentOther_PhoneRelease;
|
import static com.pudonghot.yo.model.agentevent.EventType.AgentOther_PhoneRelease;
|
||||||
import static com.pudonghot.yo.model.agentevent.EventType.AgentEvent_Customer_Release;
|
import static com.pudonghot.yo.model.agentevent.EventType.AgentEvent_Customer_Release;
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.pudonghot.yo.fsagent.service;
|
||||||
|
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date Sep 11, 2021 20:27:22
|
||||||
|
*/
|
||||||
|
public interface CallDetailRecordService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert cdr
|
||||||
|
*
|
||||||
|
* @param req req
|
||||||
|
*/
|
||||||
|
void insert(CallDetailRecordBase req);
|
||||||
|
}
|
@ -103,8 +103,9 @@ public class CampaignDialServiceImpl implements CampaignDialService {
|
|||||||
LogMDC.setTraceId(uuid);
|
LogMDC.setTraceId(uuid);
|
||||||
callUuidList.add(uuid);
|
callUuidList.add(uuid);
|
||||||
|
|
||||||
final List<String> channelVars = Arrays.asList(
|
val channelVars = Arrays.<String>asList(
|
||||||
"x_account=SYSTEM",
|
"x_account=SYSTEM",
|
||||||
|
"x_agent_type=SYSTEM",
|
||||||
"origination_uuid=" + uuid,
|
"origination_uuid=" + uuid,
|
||||||
"sip_invite_call_id=" + uuid,
|
"sip_invite_call_id=" + uuid,
|
||||||
"originate_timeout=30",
|
"originate_timeout=30",
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.pudonghot.yo.fsagent.service.impl;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import com.pudonghot.yo.mapper.CallDetailRecordMapper;
|
||||||
|
import com.pudonghot.yo.mapper.CallDetailRecordAllMapper;
|
||||||
|
import com.pudonghot.yo.model.domain.CallDetailRecordBase;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import com.pudonghot.yo.fsagent.service.CallDetailRecordService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date Sep 11, 2021 20:32:27
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class CallDetailRecordServiceImpl
|
||||||
|
implements CallDetailRecordService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CallDetailRecordMapper callDetailRecordMapper;
|
||||||
|
@Autowired
|
||||||
|
private CallDetailRecordAllMapper callDetailRecordAllMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void insert(final CallDetailRecordBase req) {
|
||||||
|
log.debug("Insert call detail [{}].", req);
|
||||||
|
callDetailRecordAllMapper.insert(req);
|
||||||
|
// callDetailRecordMapper.insert(req);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.pudonghot.yo.fsagent.service.request;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.ToString;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Donghuang
|
||||||
|
* @date Sep 08, 2021 10:50:55
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
public class CallDetailtRecordCreateServReq implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Integer tenantId;
|
||||||
|
private String tenantCode;
|
||||||
|
private String account;
|
||||||
|
private String connId;
|
||||||
|
private String dialType;
|
||||||
|
private String callType;
|
||||||
|
private String agentType;
|
||||||
|
private Integer campaignId;
|
||||||
|
private String caseKey;
|
||||||
|
|
||||||
|
private String uuid;
|
||||||
|
private String callUuid;
|
||||||
|
private String sipCallId;
|
||||||
|
private String callerNumber;
|
||||||
|
private String calledNumber;
|
||||||
|
private Integer trunkId;
|
||||||
|
private String callingPartyNumber;
|
||||||
|
private Date startStamp;
|
||||||
|
private Date answerStamp;
|
||||||
|
private Date endStamp;
|
||||||
|
private Long duration;
|
||||||
|
private Long mduration;
|
||||||
|
private Long billsec;
|
||||||
|
private Long billmsec;
|
||||||
|
private String endpointDisposition;
|
||||||
|
private String hangupCause;
|
||||||
|
private String hangupDisposition;
|
||||||
|
}
|
@ -7,15 +7,15 @@
|
|||||||
|
|
||||||
<profile name="default">
|
<profile name="default">
|
||||||
<settings>
|
<settings>
|
||||||
<!-- the format of data to send, defaults to xml -->
|
<!-- the format json|xml of data to send, defaults to xml -->
|
||||||
<!-- <param name="format" value="json|xml"/> -->
|
|
||||||
<param name="format" value="json"/>
|
<param name="format" value="json"/>
|
||||||
|
|
||||||
<!-- the url to post to if blank web posting is disabled -->
|
<!-- the url to post to if blank web posting is disabled -->
|
||||||
<param name="url" value="${model.postUrl}"/>
|
<param name="url" value="${model.postUrl}"/>
|
||||||
|
|
||||||
|
<!-- <#noparse> -->
|
||||||
<!-- optional: credentials to send to web server -->
|
<!-- optional: credentials to send to web server -->
|
||||||
<!-- <param name="cred" value="user:pass"/> -->
|
<!-- <param name="cred" value="user:pass"/> -->
|
||||||
|
|
||||||
<!-- the total number of retries (not counting the first 'try') to post to webserver incase of failure -->
|
<!-- the total number of retries (not counting the first 'try') to post to webserver incase of failure -->
|
||||||
<param name="retries" value="2"/>
|
<param name="retries" value="2"/>
|
||||||
@ -80,8 +80,8 @@
|
|||||||
<!-- <param name="cookie-file" value="/tmp/cookie-mod_format_cdr_curl.txt"/> -->
|
<!-- <param name="cookie-file" value="/tmp/cookie-mod_format_cdr_curl.txt"/> -->
|
||||||
|
|
||||||
<!-- Whether to URL encode the individual JSON values. Defaults to true, set to false for standard JSON. -->
|
<!-- Whether to URL encode the individual JSON values. Defaults to true, set to false for standard JSON. -->
|
||||||
<param name="encode-values" value="true"/>
|
<param name="encode-values" value="false"/>
|
||||||
|
<!-- </#noparse> -->
|
||||||
</settings>
|
</settings>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user