增加重呼
This commit is contained in:
parent
97fcf9392a
commit
bc57ca2d3d
@ -8,7 +8,6 @@ import java.util.ArrayList;
|
||||
import com.wacai.tigon.form.FormList;
|
||||
import com.wacai.tigon.mybatis.Search;
|
||||
import com.wacai.tigon.model.ViewModel;
|
||||
import com.pudonghot.yo.mapper.CampaignMapper;
|
||||
import com.pudonghot.yo.model.domain.Campaign;
|
||||
import com.wacai.tigon.web.annotation.ListApi;
|
||||
import com.wacai.tigon.web.controller.ArgQuery;
|
||||
@ -16,12 +15,18 @@ import com.pudonghot.yo.cms.auth.SessionAbility;
|
||||
import com.wacai.tigon.web.annotation.FilterCol;
|
||||
import com.pudonghot.yo.model.domain.CallingList;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import com.pudonghot.yo.cms.service.CampaignService;
|
||||
import com.pudonghot.yo.cms.annotation.TenantResource;
|
||||
import com.pudonghot.yo.cms.service.CallingListService;
|
||||
import com.pudonghot.yo.model.domain.CallingListPrepared;
|
||||
import com.pudonghot.yo.model.dbobject.CallingListSummary;
|
||||
import com.wacai.tigon.web.controller.BaseCrudController;
|
||||
import com.pudonghot.yo.cms.response.RespCallingListSummary;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import com.pudonghot.yo.cms.form.update.UpdateFormCallingList;
|
||||
import com.pudonghot.yo.cms.form.create.CreateFormCallingList;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import com.pudonghot.yo.cms.service.CallingListPreparedService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
@ -47,7 +52,9 @@ public class CallingListController
|
||||
CreateFormCallingList,
|
||||
UpdateFormCallingList> implements SessionAbility {
|
||||
@Autowired
|
||||
private CampaignMapper campaignMapper;
|
||||
private CampaignService campaignService;
|
||||
@Autowired
|
||||
private CallingListPreparedService callingListPreparedService;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@ -56,21 +63,20 @@ public class CallingListController
|
||||
protected void after(final ArgQuery<?> arg) {
|
||||
super.after(arg);
|
||||
if (arg.getType() == ArgQuery.Type.LIST) {
|
||||
final ViewModel<List<ViewModel<CallingList>>> vmList =
|
||||
(ViewModel<List<ViewModel<CallingList>>>) arg.getResult();
|
||||
val vmList = (ViewModel<List<ViewModel<CallingList>>>) arg.getResult();
|
||||
vmList.getData().forEach(vm ->
|
||||
vm.setAttr("campaign", campaignMapper.find(new Search(vm.getData().getCampaignId())))
|
||||
vm.setAttr("campaign", campaignService.find(new Search(vm.getData().getCampaignId())))
|
||||
);
|
||||
}
|
||||
final ViewModel<?> vm = arg.getResult();
|
||||
vm.setAttr("campaignList", campaignMapper.list(new Search(Campaign.ACTIVE, true)));
|
||||
val vm = arg.getResult();
|
||||
vm.setAttr("campaignList", campaignService.list(new Search(Campaign.ACTIVE, true)));
|
||||
vm.setAttr("callingListStatus", status());
|
||||
}
|
||||
|
||||
@RequestMapping("/status")
|
||||
public List<Map<String, Object>> status() {
|
||||
CallingList.Status[] statusArr = CallingList.Status.values();
|
||||
List<Map<String, Object>> statusList = new ArrayList<>(statusArr.length);
|
||||
val statusArr = CallingList.Status.values();
|
||||
val statusList = new ArrayList<Map<String, Object>>(statusArr.length);
|
||||
for (CallingList.Status status : CallingList.Status.values()) {
|
||||
statusList.add(
|
||||
new HashMap<String, Object>(4) {{
|
||||
@ -82,14 +88,25 @@ public class CallingListController
|
||||
}
|
||||
|
||||
@RequestMapping("/summary")
|
||||
public RespCallingListSummary summary() {
|
||||
// TODO summary
|
||||
val summary = new RespCallingListSummary();
|
||||
summary.setTotal(queryService.count(null));
|
||||
summary.setCalled(queryService.count(
|
||||
new Search(CallingList.STATUS,
|
||||
CallingList.Status.CALLED)));
|
||||
public ViewModel<CallingListSummary> summary(@RequestParam("campaignId") Integer campaignId) {
|
||||
val vm = new ViewModel<>(((CallingListService) queryService).summary(campaignId));
|
||||
vm.setAttr("prepared", callingListPreparedService.count(
|
||||
new Search(CallingListPrepared.CAMPAIGN_ID, campaignId)
|
||||
.eq(CallingListPrepared.ACTIVE, true)));
|
||||
return vm;
|
||||
}
|
||||
|
||||
return summary;
|
||||
@PostMapping("/redial")
|
||||
public int redial(@RequestParam("campaignId") Integer campaignId) {
|
||||
return ((CallingListService) queryService).redial(campaignId);
|
||||
}
|
||||
|
||||
@PostMapping("/import-prepared")
|
||||
public int importPrepared(
|
||||
@RequestParam("campaignId")
|
||||
Integer campaignId,
|
||||
@RequestParam("limit")
|
||||
Integer limit) {
|
||||
return ((CallingListService) queryService).importPrepared(campaignId, limit);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.pudonghot.yo.cms.service;
|
||||
|
||||
import com.wacai.tigon.service.BaseCrudService;
|
||||
import com.pudonghot.yo.model.domain.CallingListPrepared;
|
||||
|
||||
/**
|
||||
* @author Donghuang
|
||||
* @date Sep 20, 2020 14:42:24
|
||||
*/
|
||||
public interface CallingListPreparedService
|
||||
extends BaseCrudService<Integer, CallingListPrepared> {
|
||||
}
|
@ -1,16 +1,41 @@
|
||||
package com.pudonghot.yo.cms.service;
|
||||
|
||||
import com.pudonghot.yo.cms.form.create.CreateFormCallingList;
|
||||
import com.pudonghot.yo.cms.form.update.UpdateFormCallingList;
|
||||
import com.pudonghot.yo.model.domain.CallingList;
|
||||
import com.wacai.tigon.service.BaseCrudByFormService;
|
||||
import com.pudonghot.yo.model.dbobject.CallingListSummary;
|
||||
import com.pudonghot.yo.cms.form.create.CreateFormCallingList;
|
||||
import com.pudonghot.yo.cms.form.update.UpdateFormCallingList;
|
||||
|
||||
/**
|
||||
* @author bingpo
|
||||
* @date 2020/3/16 下午3:46
|
||||
* @author Donghuang
|
||||
* @date Sep 20, 2020 12:12:45
|
||||
*/
|
||||
public interface CallingListService
|
||||
extends BaseCrudByFormService<Integer, CallingList,
|
||||
CreateFormCallingList,
|
||||
UpdateFormCallingList> {
|
||||
|
||||
/**
|
||||
* find campaign calling list summary
|
||||
* @param campaignId
|
||||
* @return
|
||||
*/
|
||||
CallingListSummary summary(Integer campaignId);
|
||||
|
||||
/**
|
||||
* redial calling list
|
||||
*
|
||||
* @param campaignId campaign id
|
||||
* @return redial rows
|
||||
*/
|
||||
int redial(Integer campaignId);
|
||||
|
||||
/**
|
||||
* import prepared calling list
|
||||
*
|
||||
* @param campaignId campaign id
|
||||
* @param rows import rows
|
||||
* @return import rows
|
||||
*/
|
||||
int importPrepared(Integer campaignId, Integer rows);
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.pudonghot.yo.cms.service.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.pudonghot.yo.mapper.CallingListPreparedMapper;
|
||||
import com.pudonghot.yo.model.domain.CallingListPrepared;
|
||||
import com.wacai.tigon.service.support.BaseCrudServiceSupport;
|
||||
import com.pudonghot.yo.cms.service.CallingListPreparedService;
|
||||
|
||||
/**
|
||||
* @author Donghuang
|
||||
* @date Sep 20, 2020 14:43:56
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class CallingListPreparedServiceImpl
|
||||
extends BaseCrudServiceSupport<Integer,
|
||||
CallingListPrepared,
|
||||
CallingListPreparedMapper>
|
||||
implements CallingListPreparedService {
|
||||
}
|
@ -1,21 +1,27 @@
|
||||
package com.pudonghot.yo.cms.service.impl;
|
||||
|
||||
import com.pudonghot.yo.cms.form.create.CreateFormCallingList;
|
||||
import com.pudonghot.yo.cms.form.update.UpdateFormCallingList;
|
||||
import com.pudonghot.yo.cms.service.CallingListService;
|
||||
import com.pudonghot.yo.mapper.CallingListMapper;
|
||||
import lombok.val;
|
||||
import java.util.HashMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.wacai.tigon.mybatis.Search;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.pudonghot.yo.mapper.CampaignMapper;
|
||||
import com.pudonghot.yo.model.domain.CallingList;
|
||||
import com.pudonghot.yo.model.domain.Campaign;
|
||||
import com.wacai.tigon.service.support.BaseCrudByFormServiceSupport;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.util.Assert;
|
||||
import com.pudonghot.yo.mapper.CallingListMapper;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import com.pudonghot.yo.cms.service.CallingListService;
|
||||
import com.pudonghot.yo.model.domain.CallingListPrepared;
|
||||
import com.pudonghot.yo.mapper.CallingListPreparedMapper;
|
||||
import com.pudonghot.yo.model.dbobject.CallingListSummary;
|
||||
import com.pudonghot.yo.cms.form.create.CreateFormCallingList;
|
||||
import com.pudonghot.yo.cms.form.update.UpdateFormCallingList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.wacai.tigon.service.support.BaseCrudByFormServiceSupport;
|
||||
|
||||
/**
|
||||
* @author bingpo
|
||||
* @date 2020/3/16 下午4:00
|
||||
* @author Donghuang
|
||||
* @date Sep 20, 2020 14:02:13
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -28,14 +34,54 @@ public class CallingListServiceImpl
|
||||
implements CallingListService {
|
||||
@Autowired
|
||||
private CampaignMapper campaignMapper;
|
||||
@Autowired
|
||||
private CallingListPreparedMapper callingListPreparedMapper;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void beforeCreate(CreateFormCallingList form, CallingList model) {
|
||||
protected void beforeCreate(final CreateFormCallingList form, final CallingList model) {
|
||||
super.beforeCreate(form, model);
|
||||
final Integer campaignId = form.getCampaignId();
|
||||
final Campaign campaign = campaignMapper.find(campaignId);
|
||||
Assert.state(campaign != null, "无效的campaign[ " + campaignId + " ]");
|
||||
val campaignId = form.getCampaignId();
|
||||
val campaign = campaignMapper.find(campaignId);
|
||||
Assert.state(campaign != null,
|
||||
() -> "无效的campaign[ " + campaignId + " ]");
|
||||
model.setCampaignKey(campaign.getCampaignKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public CallingListSummary summary(final Integer campaignId) {
|
||||
return mapper.summary(campaignId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int redial(final Integer campaignId) {
|
||||
return mapper.redial(campaignId);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int importPrepared(final Integer campaignId,
|
||||
final Integer limit) {
|
||||
val batchKey = DateFormatUtils.format(
|
||||
System.currentTimeMillis(),
|
||||
"yyyyMMddHHmmss") + "_FRESH_DATA";
|
||||
val update = new HashMap<String, Object>();
|
||||
update.put(CallingListPrepared.EXPORT_BATCH_KEY, batchKey);
|
||||
val rows = callingListPreparedMapper.update(update,
|
||||
new Search(CallingListPrepared.CAMPAIGN_ID, campaignId)
|
||||
.eq(CallingListPrepared.ACTIVE, true)
|
||||
.isNull(CallingListPrepared.EXPORT_BATCH_KEY).limit(limit));
|
||||
mapper.insertPrepared(batchKey);
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@
|
||||
<!-- ip address to bind to, DO NOT USE HOSTNAMES ONLY IP ADDRESSES -->
|
||||
<param name="sip-ip" value="$${local_ip_v4}" />
|
||||
<param name="hold-music" value="$${hold_music}" />
|
||||
<param name="apply-nat-acl" value="nat.auto" />
|
||||
<!--<param name="apply-nat-acl" value="nat.auto" />-->
|
||||
|
||||
<!-- (default true) set to false if you do not wish to have called party info in 1XX responses -->
|
||||
<!-- <param name="cid-in-1xx" value="false" /> -->
|
||||
|
@ -28,4 +28,6 @@ if [ -z "$1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mvn -T 4C clean -pl $1 -am -DskipTests spring-boot:run
|
||||
mvn -T 4C clean -pl $1 -am -DskipTests \
|
||||
spring-boot:run
|
||||
|
||||
|
@ -1,11 +1,37 @@
|
||||
package com.pudonghot.yo.mapper;
|
||||
|
||||
import com.pudonghot.yo.model.domain.CallingList;
|
||||
import com.wacai.tigon.mybatis.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.pudonghot.yo.model.domain.CallingList;
|
||||
import com.pudonghot.yo.model.dbobject.CallingListSummary;
|
||||
|
||||
/**
|
||||
* @author Donghuang <br>
|
||||
* Feb 05, 2020 12:55:43
|
||||
*/
|
||||
public interface CallingListMapper extends BaseMapper<Integer, CallingList> {
|
||||
|
||||
/**
|
||||
* query campaign calling list summary
|
||||
*
|
||||
* @param campaignId campaign id
|
||||
* @return campaign calling list summary
|
||||
*/
|
||||
CallingListSummary summary(@Param("campaignId") Integer campaignId);
|
||||
|
||||
/**
|
||||
* redial not answered
|
||||
*
|
||||
* @param campaignId campaign id
|
||||
* @return effective rows
|
||||
*/
|
||||
int redial(@Param("campaignId") Integer campaignId);
|
||||
|
||||
/**
|
||||
* insert prepared calling list
|
||||
*
|
||||
* @param exportBatchKey export batch key
|
||||
* @return
|
||||
*/
|
||||
void insertPrepared(@Param("exportBatchKey") String exportBatchKey);
|
||||
}
|
||||
|
@ -9,17 +9,65 @@
|
||||
-->
|
||||
<mapper namespace="com.pudonghot.yo.mapper.CallingListMapper">
|
||||
|
||||
<select id="statCampaign" resultType="map">
|
||||
<select id="summary" resultType="com.pudonghot.yo.model.dbobject.CallingListSummary">
|
||||
select
|
||||
count(*) count,
|
||||
count(case when status = 'READY' then 1 end) count_ready,
|
||||
count(case when status = 'ACHIEVED' then 1 end) count_achieved,
|
||||
count(case when status = 'CALLED' then 1 end) count_called,
|
||||
count(case when status = 'CANCELED' then 1 end) count_canceled,
|
||||
count(case when status = 'CALLED' and connected = 1 then 1 end) count_connected,
|
||||
count(case when status = 'CALLED' and connected = 0 then 1 end) count_not_connected
|
||||
from br_calling_list
|
||||
count(1) total,
|
||||
count(if (status = 'READY', 1, null)) ready,
|
||||
count(if (status = 'ACHIEVED', 1, null)) achieved,
|
||||
count(if (status = 'DIALING', 1, null)) dialing,
|
||||
|
||||
count(if (called_times = 1, 1, null)) first_called,
|
||||
count(if (called_times = 2, 1, null)) twice_called,
|
||||
<![CDATA[
|
||||
count(if (
|
||||
status = 'CALLED'
|
||||
and called_times = 1
|
||||
and last_call_duration < 3
|
||||
and last_call_start_time between now() - interval 12 hour and now() - interval 240 minute,
|
||||
1, null)) redial,
|
||||
]]>
|
||||
count(if (last_connected, 1, null)) answered
|
||||
|
||||
from <include refid="table" />
|
||||
where campaign_id = #{campaignId}
|
||||
and active = 1
|
||||
</select>
|
||||
|
||||
<update id="redial">
|
||||
<![CDATA[
|
||||
update br_calling_list
|
||||
set status = 'READY',
|
||||
daily_from = time_to_sec(now()),
|
||||
daily_to = time_to_sec(now() + interval 60 minute)
|
||||
where campaign_id = #{campaignId}
|
||||
and active = 1
|
||||
and status = 'CALLED'
|
||||
and called_times = 1
|
||||
and last_call_duration < 3
|
||||
and last_call_start_time between now() - interval 12 hour
|
||||
and now() - interval 240 minute
|
||||
]]>
|
||||
</update>
|
||||
|
||||
<insert id="insertPrepared">
|
||||
insert into br_calling_list(
|
||||
campaign_id, campaign_key,
|
||||
added_time, task_key,
|
||||
case_key, phone, status,
|
||||
case_data, meta_data,
|
||||
daily_from, daily_to,
|
||||
note)
|
||||
|
||||
select campaign_id, campaign_key,
|
||||
now() added_time,
|
||||
export_batch_key task_key,
|
||||
case_key, phone, 'READY' status,
|
||||
case_data, meta_data,
|
||||
time_to_sec('09:30') daily_from,
|
||||
time_to_sec('12:00') daily_to,
|
||||
'NEW_DATA' note
|
||||
from br_calling_list_prepared
|
||||
where export_batch_key = #{exportBatchKey}
|
||||
|
||||
</insert>
|
||||
</mapper>
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.pudonghot.yo.mapper;
|
||||
|
||||
import com.wacai.tigon.mybatis.BaseMapper;
|
||||
import com.pudonghot.yo.model.domain.CallingListPrepared;
|
||||
|
||||
/**
|
||||
* @author Donghuang <br>
|
||||
* Feb 05, 2020 12:55:43
|
||||
*/
|
||||
public interface CallingListPreparedMapper extends BaseMapper<Integer, CallingListPrepared> {
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<?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 20, 2020 13:21:51
|
||||
*/
|
||||
-->
|
||||
<mapper namespace="com.pudonghot.yo.mapper.CallingListPreparedMapper">
|
||||
</mapper>
|
@ -1,11 +1,12 @@
|
||||
package com.pudonghot.yo.mapper;
|
||||
|
||||
import lombok.val;
|
||||
import org.junit.Test;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.runner.RunWith;
|
||||
import com.wacai.tigon.mybatis.Search;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
@ -23,4 +24,16 @@ public class CallingListMapperTest {
|
||||
public void testList() {
|
||||
mapper.list(new Search());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSummary() {
|
||||
val summary = mapper.summary(8);
|
||||
log.info("Summary: {}", summary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRedial() {
|
||||
val result = mapper.redial(8);
|
||||
log.info("Redial: {}", result);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.pudonghot.yo.mapper;
|
||||
|
||||
import org.junit.Test;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.runner.RunWith;
|
||||
import com.wacai.tigon.mybatis.Search;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Donghuang <br>
|
||||
* Feb 05, 2020 12:57:01
|
||||
*/
|
||||
@Slf4j
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath*:spring/spring-*.xml")
|
||||
public class CallingListPreparedMapperTest {
|
||||
@Autowired
|
||||
private CallingListPreparedMapper mapper;
|
||||
|
||||
@Test
|
||||
public void testList() {
|
||||
mapper.list(new Search());
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.pudonghot.yo.model.dbobject;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Donghuang
|
||||
* @date Sep 15, 2020 23:59:44
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
public class CallingListSummary implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 总量
|
||||
*/
|
||||
private Integer total;
|
||||
|
||||
/**
|
||||
* 首次拨打
|
||||
*/
|
||||
private Integer firstCalled;
|
||||
|
||||
/**
|
||||
* 二次拨打
|
||||
*/
|
||||
private Integer twiceCalled;
|
||||
|
||||
/**
|
||||
* 就绪
|
||||
*/
|
||||
private Integer ready;
|
||||
|
||||
/**
|
||||
* 加载中
|
||||
*/
|
||||
private Integer achieved;
|
||||
|
||||
/**
|
||||
* 拨打中
|
||||
*/
|
||||
private Integer dialing;
|
||||
|
||||
/**
|
||||
* 应答
|
||||
*/
|
||||
private Integer answered;
|
||||
|
||||
/**
|
||||
* 重呼
|
||||
*/
|
||||
private Integer redial;
|
||||
}
|
@ -26,6 +26,8 @@ public class CallingList extends BaseDomain {
|
||||
@NotUpdate
|
||||
private String campaignKey;
|
||||
@NotUpdate
|
||||
private Type type;
|
||||
@NotUpdate
|
||||
private Date addedTime;
|
||||
private DailyTime dailyFrom;
|
||||
private DailyTime dailyTo;
|
||||
@ -52,4 +54,9 @@ public class CallingList extends BaseDomain {
|
||||
public enum Status {
|
||||
NOT_READY, READY, ACHIEVED, DIALING, CALLED, CANCELED
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
FRESH,
|
||||
OLD
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package com.pudonghot.yo.model.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import java.util.Date;
|
||||
import com.wacai.tigon.mybatis.Table;
|
||||
import com.wacai.tigon.mybatis.NotUpdate;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
|
||||
/**
|
||||
* @author Donghuang
|
||||
* @date Sep 20, 2020 13:08:26
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Table("br_calling_list_prepared")
|
||||
@FieldNameConstants(prefix = "")
|
||||
public class CallingListPrepared extends BaseDomain {
|
||||
@NotUpdate
|
||||
private Integer tenantId;
|
||||
@NotUpdate
|
||||
private String tenantCode;
|
||||
@NotUpdate
|
||||
private Integer campaignId;
|
||||
@NotUpdate
|
||||
private String campaignKey;
|
||||
@NotUpdate
|
||||
private Date addedTime;
|
||||
@NotUpdate
|
||||
private String phone;
|
||||
@NotUpdate
|
||||
private String insertBatchKey;
|
||||
/**
|
||||
* 导出到拨打名单Key
|
||||
*/
|
||||
private String exportBatchKey;
|
||||
@NotUpdate
|
||||
private String caseKey;
|
||||
@NotUpdate
|
||||
private String caseData;
|
||||
@NotUpdate
|
||||
private String metaData;
|
||||
}
|
@ -129,6 +129,10 @@ Router.map(function() {
|
||||
this.route('create');
|
||||
this.route('edit', {path: '/:id/edit'});
|
||||
});
|
||||
|
||||
this.route('calling-list', function() {
|
||||
this.route('summary');
|
||||
});
|
||||
});
|
||||
|
||||
export default Router;
|
||||
|
32
web/cms/app/routes/calling-list/summary.js
Normal file
32
web/cms/app/routes/calling-list/summary.js
Normal file
@ -0,0 +1,32 @@
|
||||
import BaseRoute from '../base';
|
||||
|
||||
export default BaseRoute.extend({
|
||||
breadcrumbs: [{route: 'campaign.list', text: '外呼活动列表'}, {text: '呼叫名单管理'}],
|
||||
queryParams: {
|
||||
campaignId: {
|
||||
refreshModel: true
|
||||
}
|
||||
},
|
||||
model(params) {
|
||||
return this.get('service').ajaxGet('summary', params);
|
||||
},
|
||||
actions: {
|
||||
importPrepared() {
|
||||
console.log('log import prepared.');
|
||||
},
|
||||
redial(campaignId) {
|
||||
const me = this;
|
||||
console.log('Redial campaign ', campaignId);
|
||||
if (!me.get('controller.model.redial')) {
|
||||
me.get('message').warn('没有可重呼的数据');
|
||||
return;
|
||||
}
|
||||
me.get('dialog').confirm('确认要重呼4小时前未接通拨打名单吗?', () => {
|
||||
me.get('service').ajaxPost('redial', {campaignId}).then(count => {
|
||||
me.get('message').alert('重呼成功,重呼数据量: ' + count);
|
||||
me.refresh();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
35
web/cms/app/templates/calling-list/summary.hbs
Normal file
35
web/cms/app/templates/calling-list/summary.hbs
Normal file
@ -0,0 +1,35 @@
|
||||
{{#form-content}}
|
||||
{{!-- {{#form-input label='未入库新数据'}}
|
||||
<input value="{{model.prepared}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-6" />
|
||||
<button {{action (route-action 'importPrepared')}} style="margin-left: 2px;" class="btn btn-sm btn-info">导入</button>
|
||||
{{/form-input}} --}}
|
||||
{{#form-input label='名单总量'}}
|
||||
<input value="{{model.total}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-12" />
|
||||
{{/form-input}}
|
||||
{{#form-input label='首次拨打量'}}
|
||||
<input value="{{model.firstCalled}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-12" />
|
||||
{{/form-input}}
|
||||
{{#form-input label='二次拨打量'}}
|
||||
<input value="{{model.twiceCalled}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-12" />
|
||||
{{/form-input}}
|
||||
{{#form-input label='应答量'}}
|
||||
<input value="{{model.answered}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-12" />
|
||||
{{/form-input}}
|
||||
{{#form-input label='未拨打'}}
|
||||
<input value="{{model.ready}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-12" />
|
||||
{{/form-input}}
|
||||
{{#form-input label='加载中'}}
|
||||
<input value="{{model.achieved}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-12" />
|
||||
{{/form-input}}
|
||||
{{#form-input label='呼叫中'}}
|
||||
<input value="{{model.dialing}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-12" />
|
||||
{{/form-input}}
|
||||
{{#form-input label='可重呼量'}}
|
||||
<input value="{{model.redial}}" style="border: 0; background-color: #fff; color: #000;" readonly type="text" class="col-sm-6" />
|
||||
<button {{action (route-action 'redial' campaignId)}} style="margin-left: 2px;" class="btn btn-sm btn-info">重呼</button>
|
||||
{{/form-input}}
|
||||
|
||||
<hr />
|
||||
{{!-- {{form-footer-buttons type='update'}} --}}
|
||||
{{/form-content}}
|
||||
{{outlet}}
|
@ -149,6 +149,15 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
{{#has-perm 'PERM_VIEW_CALLING_LIST_SUMMARY'}}
|
||||
{{#link-to 'calling-list.summary'
|
||||
(query-params campaignId=it.id)
|
||||
class='btn btn-xs btn-info'
|
||||
data-rel='tooltip'
|
||||
title='呼叫名单概览'}}
|
||||
<i class="ace-icon fa fa-sliders bigger-120"></i>
|
||||
{{/link-to}}
|
||||
{{/has-perm}}
|
||||
{{#has-perm 'PERM_VIEW_CAMPAIGN_EDIT'}}
|
||||
{{status-toggle-button model=it}}
|
||||
{{edit-btn route-name='campaign.edit' model-id=it.id perm='PERM_VIEW_CAMPAIGN_EDIT'}}
|
||||
|
11
web/cms/tests/unit/routes/calling-list/summary-test.js
Normal file
11
web/cms/tests/unit/routes/calling-list/summary-test.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
|
||||
module('Unit | Route | calling-list/summary', function(hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
test('it exists', function(assert) {
|
||||
let route = this.owner.lookup('route:calling-list/summary');
|
||||
assert.ok(route);
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user