增加拨打限制规则

This commit is contained in:
Shaun Chyxion 2020-11-05 23:21:21 +08:00
parent 72dd262f17
commit 6f663c2ee5
6 changed files with 80 additions and 80 deletions

View File

@ -24,17 +24,6 @@ public interface CallDetailRecordMapper extends BaseMapper<Integer, CallDetailRe
@Param("tenantId") Integer tenantId, @Param("tenantId") Integer tenantId,
@Param("calledNumber") String calledNumber); @Param("calledNumber") String calledNumber);
/**
* 累计不超过8次T-2内未接通过且今日最多拨打过一次
*
* @param tenantId tenant id
* @param calledNumber called number
* @return true if number never connected and today at most once
*/
boolean calledNumberCanDial(
@Param("tenantId") Integer tenantId,
@Param("calledNumber") String calledNumber);
/** /**
* account report * account report
* @param arg arg * @param arg arg

View File

@ -34,63 +34,6 @@
) t ) t
</select> </select>
<select id="calledNumberCanDial" resultType="boolean">
select count(1) from (
select c.phone from (
select #{calledNumber} phone
) c
<!-- T-2日内有接通过 -->
<![CDATA[
left join (select called_number
from br_call_detail_record
where start_stamp > date(subdate(now(), 2))
and tenant_id = #{tenantId}
group by called_number
having count(answer_stamp) > 0) t1
]]>
on c.phone = t1.called_number
<!-- 过去累计拨打次数超过7 -->
<![CDATA[
left join (select called_number
from br_call_detail_record
where start_stamp > date(subdate(now(), 21))
and tenant_id = #{tenantId}
group by called_number
having count(id) > 7) t2
]]>
on c.phone = t2.called_number
<!-- 今日拨打次数超过1 -->
<![CDATA[
left join (select called_number
from br_call_detail_record
where start_stamp > date(now())
and tenant_id = #{tenantId}
group by called_number
having count(id) > 1) t3
]]>
on c.phone = t3.called_number
<!-- 4小时内拨打过 -->
<![CDATA[
left join (select called_number
from br_call_detail_record
where start_stamp > date(now())
and tenant_id = #{tenantId}
group by called_number
having max(start_stamp) > now() - interval 4 hour) t4
]]>
on c.phone = t4.called_number
where t1.called_number is null
and t2.called_number is null
and t3.called_number is null
and t4.called_number is null
) t
</select>
<select id="accountReport" resultType="com.pudonghot.yo.model.dbobject.CallDetailReport"> <select id="accountReport" resultType="com.pudonghot.yo.model.dbobject.CallDetailReport">
select account, select account,
dial_type, dial_type,

View File

@ -44,12 +44,6 @@ public class CallDetailRecordMapperTest {
log.info("Result [{}].", result); log.info("Result [{}].", result);
} }
@Test
public void testCanDial() {
val result = mapper.calledNumberCanDial(1, "13764268709");
log.info("CanDial [{}].", result);
}
@Test @Test
public void testAccountReport() throws ParseException { public void testAccountReport() throws ParseException {
val arg = new ReqCallDetailRecordAccountReport(); val arg = new ReqCallDetailRecordAccountReport();

View File

@ -19,7 +19,10 @@ public enum ErrorCode {
// 客户号码 // 客户号码
DIAL_BLACKLIST("001-004", "黑名单号码"), DIAL_BLACKLIST("001-004", "黑名单号码"),
DIAL_OVERCLOCK("001-005", "拨打超频"), DIAL_OVERCLOCK("001-005", "拨打超频"),
DIAL_EXCEED("001-006", "拨打超限"), DIAL_EXCEED_8TIMES_IN_30DAYS("001-006", "30日内拨打超过8次"),
DIAL_EXCEED_2TIMES_TODAY("001-007", "当日拨打超过2次"),
DIAL_EXCEED_1TIMES_IN_4HOURS("001-008", "未接通4小时内拨打"),
DIAL_EXCEED_IN_T2("001-009", "T-2日未接通拨打"),
// 内部咨询 // 内部咨询
INNER_HELP_OTHER_AGENT_NOT_FOUND("002-001", "求助坐席不存在"), INNER_HELP_OTHER_AGENT_NOT_FOUND("002-001", "求助坐席不存在"),

View File

@ -4,6 +4,7 @@ import lombok.val;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.wacai.tigon.mybatis.Search; import com.wacai.tigon.mybatis.Search;
import com.pudonghot.yo.model.domain.*; import com.pudonghot.yo.model.domain.*;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.pudonghot.yo.util.PhoneNumberUtils; import com.pudonghot.yo.util.PhoneNumberUtils;
@ -30,12 +31,18 @@ import com.pudonghot.yo.service.CommonAgentStatusService;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import com.pudonghot.yo.openapi.response.RespAgentDialout; import com.pudonghot.yo.openapi.response.RespAgentDialout;
import com.pudonghot.yo.openapi.service.AgentStatusService; import com.pudonghot.yo.openapi.service.AgentStatusService;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
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 org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import static com.pudonghot.yo.model.domain.AgentStatus.State.*; import static com.pudonghot.yo.model.domain.AgentStatus.State.*;
import static com.pudonghot.yo.model.domain.AgentStatus.Status.*; import static com.pudonghot.yo.model.domain.AgentStatus.Status.*;
import static com.pudonghot.yo.model.agentevent.EventType.AgentEvent_Call_Release; import static com.pudonghot.yo.model.agentevent.EventType.AgentEvent_Call_Release;
@ -114,12 +121,65 @@ public class CallController implements SessionAbility {
return doDial(account, calledNumber); return doDial(account, calledNumber);
} }
// 过去21天累计拨打不超过7次 val calledRecordsIn30Days = callDetailRecordMapper.list(
// 过去2天未接通过 new Search()
.gt(CallDetailRecord.START_STAMP,
DateUtils.addMonths(
DateUtils.truncate(new Date(), Calendar.MONTH), -1))
.eq(CallDetailRecord.CALLED_NUMBER, calledNumber)
.eq(CallDetailRecord.TENANT_ID, tenantId)
.desc(CallDetailRecord.START_STAMP)
.limit(8));
if (calledRecordsIn30Days.isEmpty()) {
return doDial(account, calledNumber);
}
val recSize = calledRecordsIn30Days.size();
// 过去30天累计拨打不超过8次
AssertUtils.state(recSize < 8, ErrorCode.DIAL_EXCEED_8TIMES_IN_30DAYS);
// 当日拨打不超过2次 // 当日拨打不超过2次
// 当日拨打间隔为4小时 val today = DateUtils.truncate(new Date(), Calendar.DATE);
AssertUtils.state(callDetailRecordMapper.calledNumberCanDial( AssertUtils.state(calledRecordsIn30Days.stream()
tenantId, calledNumber), ErrorCode.DIAL_EXCEED); .filter(rec -> rec.getStartStamp().after(today)).count() < 2,
ErrorCode.DIAL_EXCEED_2TIMES_TODAY);
val lastRecord = calledRecordsIn30Days.get(recSize - 1);
val lastDialStamp = lastRecord.getStartStamp();
val lastNoAnswer = (lastRecord.getAnswerStamp() == null);
// 当日上一次未接通间隔4小时
if (DateUtils.isSameDay(lastDialStamp, today) && lastNoAnswer) {
AssertUtils.state(lastDialStamp.before(
DateUtils.addHours(new Date(), -4)),
ErrorCode.DIAL_EXCEED_1TIMES_IN_4HOURS);
}
// 最近<=2次日未接通则拨打日期小于T-2
final boolean check;
if (recSize > 1) {
val rec2 = calledRecordsIn30Days.get(recSize - 2);
// 同日2次
if (DateUtils.isSameDay(lastDialStamp, rec2.getStartStamp())) {
// 2次未接通
check = (lastNoAnswer && rec2.getAnswerStamp() == null);
}
// 当日1次
else {
// 未接通
check = lastNoAnswer;
}
}
else {
// 未接通
check = lastNoAnswer;
}
AssertUtils.state(!check ||
lastDialStamp.before(DateUtils.addDays(new Date(), -2)), ErrorCode.DIAL_EXCEED_IN_T2);
return doDial(account, calledNumber); return doDial(account, calledNumber);
} }

View File

@ -1,6 +1,11 @@
package com.pudonghot.yo.openapi; package com.pudonghot.yo.openapi;
import lombok.val;
import org.apache.commons.lang3.time.DateUtils;
import org.junit.Test; import org.junit.Test;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID; import java.util.UUID;
import java.io.IOException; import java.io.IOException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -29,4 +34,10 @@ public class TestDriver {
objectMapper.readValue("{\"work_no\":\"8002\",\"call_id\":\"sas665448855-8878992544\",\"cust_phone\":\"13888888888\",\"pack_type\":\"Y\",\"pack_remark\":\"新快线外呼,营销成功\",\"call_begin_date\":\"2018-05-29 09:53:30\",\"call_end_date\":\"2018-05-29 09:53:59\",\"hang_up_way\":\"01\"}", ReqSaveWorkRecord.class); objectMapper.readValue("{\"work_no\":\"8002\",\"call_id\":\"sas665448855-8878992544\",\"cust_phone\":\"13888888888\",\"pack_type\":\"Y\",\"pack_remark\":\"新快线外呼,营销成功\",\"call_begin_date\":\"2018-05-29 09:53:30\",\"call_end_date\":\"2018-05-29 09:53:59\",\"hang_up_way\":\"01\"}", ReqSaveWorkRecord.class);
log.info("Result [{}].", reqSaveWorkRecord); log.info("Result [{}].", reqSaveWorkRecord);
} }
@Test
public void testDate() {
val date = DateUtils.addMonths(DateUtils.truncate(new Date(), Calendar.HOUR), -1);
log.info("Date [{}].", date);
}
} }