电呼逻辑和分机号配置

master
wujingtao 3 years ago
parent 3103e1c529
commit 0a6693819f

@ -0,0 +1,16 @@
package com.baiye.http;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author wujingtao
* @date 2022/02/15
*/
@Data
@NoArgsConstructor
public class RollCallResponse {
private String reqid;
private String result;
private String reason;
}

@ -41,6 +41,18 @@ public class ReportController {
reportService.downloadTaskReport(response, statisticalReportDTO);
}
@GetMapping("/download/single/task")
@ApiOperation("导出单个任务的线索统计信息")
public void downloadTaskReport(HttpServletResponse response, Long id) {
reportService.downloadSingleTaskReport(response, id);
}
@GetMapping("/report/single/task")
@ApiOperation("导出单个任务的线索统计信息")
public CommonResponse<Object> reportTaskReport(Long id) {
return reportService.reportSingleTaskReport(id);
}
@PostMapping("/report/organize")
@ApiOperation("按组的统计信息")
public CommonResponse<Object> getReportByOrganize(@RequestBody StatisticalReportDTO s) {
@ -64,4 +76,5 @@ public class ReportController {
public void downloadMemberReport(HttpServletResponse response, String beginTime, String endTime, Long memberId) {
reportService.downloadMemberReport(response, beginTime, endTime, memberId);
}
}

@ -33,6 +33,16 @@ public class MemberInfoVO {
*/
@ExcelProperty(value = "小组", index = 1)
private String organizeName;
/**
* 线id
*/
@ExcelIgnore
private Long clueId;
/**
* 线
*/
@ExcelIgnore
private String clueName;
/**
*
*/

@ -35,6 +35,10 @@ public interface ReportService {
*/
void downloadTaskReport(HttpServletResponse response, StatisticalReportDTO s);
void downloadSingleTaskReport(HttpServletResponse response, Long id);
CommonResponse<Object> reportSingleTaskReport(Long id);
/**
*
*

@ -7,8 +7,15 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.exception.BadRequestException;
import com.baiye.feign.SourceClueClient;
import com.baiye.http.CommonResponse;
import com.baiye.http.DoubleCallResponse;
import com.baiye.model.enums.ResponseCode;
import com.baiye.model.vo.ResSourceLabel;
import com.baiye.modules.report.entity.dto.StatisticalReportDTO;
import com.baiye.modules.report.entity.dto.UploadTaskDTO;
import com.baiye.modules.report.entity.vo.MemberInfoVO;
@ -27,6 +34,7 @@ import com.baiye.modules.telemarkting.entity.DoubleCallInfo;
import com.baiye.util.DateTimeUtil;
import com.baiye.util.ExportExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@ -34,6 +42,7 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author wjt
@ -52,6 +61,8 @@ public class ReportServiceImpl implements ReportService {
private OrganizeRepository organizeRepository;
@Resource
private UserRepository userRepository;
@Resource
private SourceClueClient sourceClueClient;
@Override
public CommonResponse<Object> getReportByAll() {
@ -80,6 +91,167 @@ public class ReportServiceImpl implements ReportService {
ExportExcelUtil.downloadEasyExcel(response, UploadTaskDTO.class, mapByTaskUpload);
}
@Override
public void downloadSingleTaskReport(HttpServletResponse response, Long id) {
List<AllCallInfo> allCallInfos = allCallInfoRepository.selectClueByTaskId(id);
//以线索id分组
Map<Long, List<AllCallInfo>> map = new HashMap<>(16);
allCallInfos.stream().collect(Collectors.groupingBy(AllCallInfo::getClueId, Collectors.toList())).forEach(map::put);
//提取线索id
List<Long> clueIds = allCallInfos.stream().map(AllCallInfo::getClueId).collect(Collectors.toList());
//获取线索信息
List<ResSourceLabel> clueInfos = sourceClueClient.findSourceLabel(clueIds).getBody();
Map<Long, ResSourceLabel> clueMap = new HashMap<>();
if (CollUtil.isNotEmpty(clueInfos) && clueInfos != null) {
for (ResSourceLabel r : clueInfos) {
clueMap.put(r.getClueId(), r);
}
}
//获取任务的基础标签
String taskName = "";
List<String> baseLabel = new ArrayList<>();
Task taskInfo = taskRepository.findByIsDistributionAndId(DefaultNumberConstants.ONE_NUMBER, id);
if (ObjectUtil.isNull(taskInfo)) {
log.error("未找到符合的任务");
// throw new BadRequestException("未找到符合的任务");
} else {
taskName = taskInfo.getTaskName();
//任务标签
baseLabel = taskInfo.getBaseLabel();
}
Collections.sort(baseLabel);
List<LinkedList<Object>> linkedLists = new ArrayList<>();
for (Long key : map.keySet()) {
List<AllCallInfo> list = map.get(key);
//获取线索名
String clueName = null;
List<String> label = new ArrayList<>();
if (clueMap.containsKey(key)) {
ResSourceLabel resSourceLabel = clueMap.get(key);
clueName = resSourceLabel.getName();
label = JSONUtil.toList(JSONUtil.parseArray(resSourceLabel.getSourceLabel()), String.class);
}
LinkedList<Object> linkedList = getDownLoadTaskInfo(clueName, list);
for (String l : baseLabel) {
if (label.size() > 0 && label.contains(l)) {
linkedList.add("√");
} else {
linkedList.add("×");
}
}
linkedLists.add(linkedList);
}
ExportExcelUtil.dynamicHeadWrite(response, linkedLists, baseLabel, taskName);
}
@Override
public CommonResponse<Object> reportSingleTaskReport(Long id) {
List<MemberInfoVO> listVo = new ArrayList<>();
List<AllCallInfo> allCallInfos = allCallInfoRepository.selectClueByTaskId(id);
//以线索id分组
Map<Long, List<AllCallInfo>> map = new HashMap<>(16);
allCallInfos.stream().collect(Collectors.groupingBy(AllCallInfo::getClueId, Collectors.toList())).forEach(map::put);
//提取线索id
List<Long> clueIds = allCallInfos.stream().map(AllCallInfo::getClueId).collect(Collectors.toList());
//获取线索信息
List<ResSourceLabel> clueInfos = sourceClueClient.findSourceLabel(clueIds).getBody();
Map<Long, ResSourceLabel> clueMap = new HashMap<>();
if (CollUtil.isNotEmpty(clueInfos) && clueInfos != null) {
for (ResSourceLabel r : clueInfos) {
clueMap.put(r.getClueId(), r);
}
}
for (AllCallInfo info : allCallInfos) {
String clueName = "";
if (clueMap.containsKey(info.getClueId())) {
ResSourceLabel resSourceLabel = clueMap.get(info.getClueId());
clueName = resSourceLabel.getName();
}
MemberInfoVO reportTaskInfo = getReportTaskInfo(info.getClueId(), clueName, map.get(info.getClueId()));
listVo.add(reportTaskInfo);
}
return CommonResponse.createBySuccess(listVo);
}
private MemberInfoVO getReportTaskInfo(Long clueId, String clueName, List<AllCallInfo> list) {
int usrNum = list.size();
//接通数
int turnOnNum = 0;
//外呼总时长
int breatheTotalDuration = 0;
double breatheAverageDuration = 0;
double turnOnRate = 0;
for (AllCallInfo info : list) {
//接通
if (info.getStatus() == DefaultNumberConstants.TWO_NUMBER) {
turnOnNum++;
breatheTotalDuration += info.getDuration();
}
}
if (usrNum != 0) {
//接通率
turnOnRate = NumberUtil.div(turnOnNum, usrNum, 2);
if (turnOnNum != 0) {
//平均时长
breatheAverageDuration = NumberUtil.div(breatheTotalDuration, turnOnNum, 2);
}
}
MemberInfoVO memberInfoVO = new MemberInfoVO();
memberInfoVO.setClueId(clueId);
memberInfoVO.setClueName(clueName);
memberInfoVO.setUsrNum(usrNum);
memberInfoVO.setTurnOnNum(turnOnNum);
memberInfoVO.setTurnOnRate(turnOnRate);
memberInfoVO.setBreatheTotalDuration(breatheTotalDuration);
memberInfoVO.setBreatheAverageDuration(breatheAverageDuration);
return memberInfoVO;
}
private LinkedList<Object> getDownLoadTaskInfo(String clueName, List<AllCallInfo> list) {
int usrNum = list.size();
//接通数
int turnOnNum = 0;
//外呼总时长
int breatheTotalDuration = 0;
double breatheAverageDuration = 0;
double turnOnRate = 0;
for (AllCallInfo info : list) {
//接通
if (info.getStatus() == DefaultNumberConstants.TWO_NUMBER) {
turnOnNum++;
breatheTotalDuration += info.getDuration();
}
}
if (usrNum != 0) {
//接通率
turnOnRate = NumberUtil.div(turnOnNum, usrNum, 2);
if (turnOnNum != 0) {
//平均时长
breatheAverageDuration = NumberUtil.div(breatheTotalDuration, turnOnNum, 2);
}
}
LinkedList<Object> linkedList = new LinkedList<>();
linkedList.add(clueName);
linkedList.add(usrNum);
linkedList.add(turnOnNum);
linkedList.add(turnOnRate);
linkedList.add(breatheTotalDuration);
linkedList.add(breatheAverageDuration);
return linkedList;
}
@Override
public CommonResponse<Object> getReportByOrganize(StatisticalReportDTO s) {
String beginTime = s.getBeginTime();

@ -29,4 +29,13 @@ public interface TaskRepository extends JpaRepository<Task, Long>, JpaSpecificat
*/
@Query(value = "select * from tb_task t where t.is_distribution = ?1 and (coalesce (?2,null) is null or t.task_id in (?2))", nativeQuery = true)
List<Task> findAllByIsAndIsDistributionAndId(Integer isDistribution, List<Long> ids);
/**
*
*
* @param isDistribution
* @param id
* @return
*/
Task findByIsDistributionAndId(Integer isDistribution, Long id);
}

@ -0,0 +1,26 @@
package com.baiye.modules.telemarkting.api;
import com.baiye.http.CommonResponse;
import com.baiye.modules.telemarkting.service.ExtensionNumberService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author wujingtao
* @date 2022/02/14
*/
@RestController
@RequestMapping("/api")
public class ExtensionNumberController {
@Resource
private ExtensionNumberService extensionNumberService;
@GetMapping("/add/extension")
public CommonResponse<String> addNumbers(Integer minNumber, Integer maxNumber) {
extensionNumberService.addNumbers(minNumber, maxNumber);
return CommonResponse.createBySuccess();
}
}

@ -1,6 +1,7 @@
package com.baiye.modules.telemarkting.dao;
import com.baiye.modules.telemarkting.entity.AllCallInfo;
import com.baiye.modules.telemarkting.entity.CallClueInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
@ -24,6 +25,8 @@ public interface AllCallInfoRepository extends JpaRepository<AllCallInfo, Long>,
*/
AllCallInfo findBySessionId(String sessionId);
AllCallInfo findByRequestId(String requestId);
/**
*
*
@ -49,4 +52,15 @@ public interface AllCallInfoRepository extends JpaRepository<AllCallInfo, Long>,
*/
@Query(value = "select d from AllCallInfo d where d.clueId=?1 and d.memberId=?2 and d.status=?3")
List<AllCallInfo> findByClueIdAndMemberId(Long clueId, Long memberId, Integer status);
/**
* id线
*
* @param id
* @return
*/
@Query(value = "select i.* from tb_call_info i left join tb_call_clue c on i.clue_id = c.clue_id where c.task_id = ?1", nativeQuery = true)
List<AllCallInfo> selectClueByTaskId(Long id);
}

@ -15,6 +15,7 @@ import java.util.List;
*/
@Repository
public interface CallClueRepository extends JpaRepository<CallClueInfo, Long>, JpaSpecificationExecutor<CallClueInfo> {
/**
* 线
*

@ -0,0 +1,28 @@
package com.baiye.modules.telemarkting.dao;
import com.baiye.modules.telemarkting.entity.ExtensionNumber;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
/**
* @author wujingtao
* @date 2022/02/14
*/
@Repository
public interface ExtensionNumberRepository extends JpaRepository<ExtensionNumber, Long>, JpaSpecificationExecutor<ExtensionNumber> {
/**
*
*
* @param status
* @return
*/
Integer findIdByStatus(Integer status);
@Modifying
@Query(value = "update ExtensionNumber c set c.status =?1 where c.number = ?2")
void updateStatusById(Integer status, Integer id);
}

@ -0,0 +1,16 @@
package com.baiye.modules.telemarkting.dao;
import com.baiye.modules.telemarkting.entity.ExtensionUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* @author wujingtao
* @date 2022/02/14
*/
@Repository
public interface ExtensionUserRepository extends JpaRepository<ExtensionUser, Long>, JpaSpecificationExecutor<ExtensionUser> {
Integer findNumberByMemberId(Long memberId);
}

@ -0,0 +1,40 @@
package com.baiye.modules.telemarkting.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author wujingtao
* @date 2022/02/14
*
*/
@Getter
@Setter
@Entity
@Table(name = "tb_extension_number")
@EntityListeners(AuditingEntityListener.class)
public class ExtensionNumber implements Serializable {
private static final long serialVersionUID = -1387335863924769788L;
@Column(name = "status")
@ApiModelProperty(value = "状态")
private Integer status = 0;
@Id
@Column(name = "number")
@ApiModelProperty(value = "分机号")
private Integer number;
@LastModifiedDate
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

@ -0,0 +1,47 @@
package com.baiye.modules.telemarkting.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author wujingtao
* @date 2022/02/14
*
*/
@Getter
@Setter
@Entity
@Table(name = "tb_extension_user")
@EntityListeners(AuditingEntityListener.class)
public class ExtensionUser implements Serializable {
private static final long serialVersionUID = 1895747401796496801L;
@Id
@ApiModelProperty(value = "主键id自动递增")
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "number")
@ApiModelProperty(value = "分机号")
private Integer number;
@Column(name = "member_id")
@ApiModelProperty(value = "所属人id")
private Long memberId;
@Column(name = "organize_id")
@ApiModelProperty(value = "所属组id")
private Long organizeId;
@LastModifiedDate
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

@ -1,96 +0,0 @@
package com.baiye.modules.telemarkting.httpRequest;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.exception.BadRequestException;
import com.baiye.http.DoubleCallResponse;
import com.baiye.model.enums.ResponseCode;
import com.baiye.modules.telemarkting.entity.dto.TelephoneCallReqDTO;
import com.baiye.modules.telemarkting.entity.dto.TelephoneCallStopDTO;
import com.baiye.modules.telemarkting.entity.dto.TelephoneCallSystemDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author wjt
* @date 2021/12/03
*/
@Slf4j
@Component
public class CallReq {
@Value("${double.call.reqUrl}")
private String reqUrl;
@Value("${double.call.stopUrl}")
private String stopUrl;
@Value("${double.call.appid}")
private String appid;
@Value("${double.call.cdrUrl}")
private String cdrUrl;
@Value("${double.call.statusUrl}")
private String statusUrl;
public String startReq(TelephoneCallReqDTO doubleCallReq) {
log.info("=======================doubleCallReq start in {}", DateUtil.date());
return reqTask(doubleCallReq);
}
private String reqTask(TelephoneCallReqDTO telephoneCallReqDTO) {
TelephoneCallSystemDTO doubleCallSystemDTO = new TelephoneCallSystemDTO();
BeanUtil.copyProperties(telephoneCallReqDTO, doubleCallSystemDTO);
doubleCallSystemDTO.setAppid(appid);
doubleCallSystemDTO.setCompanyName(telephoneCallReqDTO.getCompanyName());
doubleCallSystemDTO.setCdrUrl(cdrUrl);
doubleCallSystemDTO.setStatusUrl(statusUrl);
int count = 0;
int flag = 3;
log.info("请求对象:{}", JSONUtil.toJsonPrettyStr(doubleCallSystemDTO));
while (count <= flag) {
HttpResponse httpResponse = sendCallReq(JSONUtil.toJsonPrettyStr(doubleCallSystemDTO), reqUrl);
if (httpResponse.isOk() && httpResponse.body().contains("success")) {
log.info("请求呼叫成功,返回值:{}", httpResponse.body());
JSONObject result = JSONUtil.parseObj(httpResponse.body());
return result.get("sessionId").toString();
} else {
count++;
String body = httpResponse.body();
log.error("请求失败,response==={}", body);
throw new BadRequestException(StringUtils.isNotBlank(body) ?
JSONUtil.toBean(body, DoubleCallResponse.class).getReason() : ResponseCode.CALL_ERROR.getDesc());
}
}
log.info("=======================doubleCallReq end in {}", DateUtil.date());
return null;
}
public Boolean stopReq(TelephoneCallStopDTO telephoneCallStopDTO) {
log.info("=======================stopReq start in {}", DateUtil.date());
return stopTask(telephoneCallStopDTO);
}
private Boolean stopTask(TelephoneCallStopDTO telephoneCallStopDTO) {
int count = 0;
int flag = 3;
while (count <= flag) {
HttpResponse httpResponse = sendCallReq(JSONUtil.toJsonPrettyStr(telephoneCallStopDTO), stopUrl);
if (httpResponse.isOk()) {
log.info("请求挂断成功,返回值:{}", httpResponse.body());
return Boolean.TRUE;
} else {
count++;
log.error("请求失败,response==={}", httpResponse.body());
}
}
log.info("=======================stopReq end in {}", DateUtil.date());
return Boolean.FALSE;
}
private HttpResponse sendCallReq(String json, String url) {
return HttpRequest.post(url).body(json).execute();
}
}

@ -4,8 +4,8 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.exception.BadRequestException;
import com.baiye.http.DoubleCallResponse;
import com.baiye.model.enums.ResponseCode;
@ -50,17 +50,20 @@ public class DoubleCallReq {
doubleCallSystemDTO.setStatusUrl(statusUrl);
log.info("请求对象:{}", JSONUtil.toJsonPrettyStr(doubleCallSystemDTO));
HttpResponse httpResponse = sendCallReq(JSONUtil.toJsonPrettyStr(doubleCallSystemDTO), reqUrl);
if (httpResponse.isOk() && httpResponse.body().contains("success")) {
log.info("请求呼叫成功,返回值:{}", httpResponse.body());
JSONObject result = JSONUtil.parseObj(httpResponse.body());
return result.get("sessionId").toString();
} else {
String body = httpResponse.body();
log.error("请求失败,response==={}", body);
throw new BadRequestException(StringUtils.isNotBlank(body) ?
JSONUtil.toBean(body, DoubleCallResponse.class).getReason() : ResponseCode.CALL_ERROR.getDesc());
if (httpResponse.isOk()) {
DoubleCallResponse doubleCallResponse = JSONUtil
.toBean(httpResponse.body(), DoubleCallResponse.class);
if (String.valueOf
(DefaultNumberConstants.ZERO_NUMBER)
.equals(doubleCallResponse.getResult())) {
return doubleCallResponse.getSessionId();
}
throw new BadRequestException
(StringUtils.isNotBlank(doubleCallResponse.getReason()) ?
doubleCallResponse.getReason()
: ResponseCode.CALL_ERROR.getDesc());
}
throw new BadRequestException(ResponseCode.CALL_ERROR.getDesc());
}
public Boolean stopReq(TelephoneCallStopDTO telephoneCallStopDTO) {

@ -1,4 +1,4 @@
/*
package com.baiye.modules.telemarkting.httpRequest;
import cn.hutool.core.codec.Base64;
@ -6,20 +6,23 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.modules.telemarkting.entity.dto.DoubleCallReqDTO;
import com.baiye.exception.BadRequestException;
import com.baiye.http.RollCallResponse;
import com.baiye.model.enums.ResponseCode;
import com.baiye.modules.telemarkting.entity.dto.RollCallSystemDTO;
import com.baiye.modules.telemarkting.entity.dto.TelephoneCallReqDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
*/
/**
* @author wujingtao
* @date 2022/02/10
*//*
*/
@Slf4j
@Component
@ -28,23 +31,24 @@ public class RollCallReq {
private String reqUrl;
@Value("${roll.call.cdrUrl}")
private String cdrUrl;
@Value("${roll.call.appId}")
private String appId;
@Value("${roll.call.token}")
private String token;
@Value("${roll.call.accountSid}")
private String accountSid;
public String startReq(DoubleCallReqDTO doubleCallReq) {
public String startReq(TelephoneCallReqDTO doubleCallReq) {
log.info("=======================RollCallReq start in {}", DateUtil.date());
return reqTask(doubleCallReq);
}
private String reqTask(DoubleCallReqDTO doubleCallReq) {
private String reqTask(TelephoneCallReqDTO doubleCallReq) {
RollCallSystemDTO rollCallSystemDTO = new RollCallSystemDTO();
String date = DateUtil.format(DateUtil.date(), "yyyyMMddHHssmm");
String sig = SecureUtil.md5(appId + token + date).toUpperCase();
String sig = SecureUtil.md5(accountSid + token + date).toUpperCase();
//设置header
String authorization = Base64.encode(appId + ":" + date);
String authorization = Base64.encode(accountSid + ":" + date);
rollCallSystemDTO.setSig(sig);
rollCallSystemDTO.setAppid(appId);
rollCallSystemDTO.setReq_id(doubleCallReq.getRequestId());
@ -52,27 +56,26 @@ public class RollCallReq {
rollCallSystemDTO.setCallee(doubleCallReq.getTelB());
rollCallSystemDTO.setIs_record(String.valueOf(DefaultNumberConstants.ONE_NUMBER));
rollCallSystemDTO.setCdr_url(cdrUrl);
int count = 0;
int flag = 3;
log.info("请求对象:{}", JSONUtil.toJsonPrettyStr(rollCallSystemDTO));
while (count <= flag) {
HttpResponse httpResponse = sendCallReq(JSONUtil.toJsonPrettyStr(rollCallSystemDTO), reqUrl, authorization);
if (httpResponse.isOk() && httpResponse.body().contains("success")) {
log.info("请求呼叫成功,返回值:{}", httpResponse.body());
JSONObject result = JSONUtil.parseObj(httpResponse.body());
return result.get("sessionid").toString();
} else {
count++;
String body = httpResponse.body();
log.error("请求失败,response==={}", body);
HttpResponse httpResponse = sendCallReq(JSONUtil.toJsonPrettyStr(rollCallSystemDTO), reqUrl, authorization);
if (httpResponse.isOk()) {
RollCallResponse doubleCallResponse = JSONUtil
.toBean(httpResponse.body(), RollCallResponse.class);
if (String.valueOf
(DefaultNumberConstants.ZERO_NUMBER)
.equals(doubleCallResponse.getResult())) {
return doubleCallResponse.getReqid();
}
throw new BadRequestException
(StringUtils.isNotBlank(doubleCallResponse.getReason()) ?
doubleCallResponse.getReason()
: ResponseCode.CALL_ERROR.getDesc());
}
log.info("=======================RollCallReq end in {}", date);
return null;
throw new BadRequestException(ResponseCode.CALL_ERROR.getDesc());
}
private HttpResponse sendCallReq(String json, String url, String authorization) {
return HttpRequest.post(url).header("Authorization", authorization).body(json).execute();
}
}
*/

@ -0,0 +1,12 @@
package com.baiye.modules.telemarkting.service;
/**
* @author wujingtao
* @date 2022/02/14
*/
public interface ExtensionNumberService {
void addNumbers(Integer minNumber, Integer maxNumber);
void assignExtensionNum(Long organizeId, Long memberId);
}

@ -0,0 +1,77 @@
package com.baiye.modules.telemarkting.service.impl;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.modules.system.domain.Organize;
import com.baiye.modules.system.service.OrganizeService;
import com.baiye.modules.telemarkting.dao.ExtensionNumberRepository;
import com.baiye.modules.telemarkting.dao.ExtensionUserRepository;
import com.baiye.modules.telemarkting.entity.ExtensionNumber;
import com.baiye.modules.telemarkting.entity.ExtensionUser;
import com.baiye.modules.telemarkting.service.ExtensionNumberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
* @author wujingtao
* @date 2022/02/14
*/
@Service
@Slf4j
public class ExtensionNumberServiceImpl implements ExtensionNumberService {
@Resource
private ExtensionNumberRepository extensionNumberRepository;
@Resource
private OrganizeService organizeService;
@Resource
private ExtensionUserRepository extensionUserRepository;
@Override
public void addNumbers(Integer minNumber, Integer maxNumber) {
List<ExtensionNumber> numbers = getNumbers(minNumber, maxNumber);
extensionNumberRepository.saveAll(numbers);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void assignExtensionNum(Long organizeId, Long memberId) {
//查询组
Organize organize = organizeService.findByOrganizeId(organizeId);
if (organize != null && organize.getCallMode() == DefaultNumberConstants.ONE_NUMBER) {
Integer numberByMemberId = extensionUserRepository.findNumberByMemberId(memberId);
if (numberByMemberId != null) {
log.info("用户 {},已经分配分机号", memberId);
return;
}
//查一个分机号
Integer idByStatus = extensionNumberRepository.findIdByStatus(DefaultNumberConstants.ZERO_NUMBER);
ExtensionUser extensionUser = new ExtensionUser();
extensionUser.setMemberId(memberId);
extensionUser.setNumber(idByStatus);
extensionUser.setOrganizeId(organizeId);
try {
extensionUserRepository.save(extensionUser);
extensionNumberRepository.updateStatusById(DefaultNumberConstants.ONE_NUMBER, idByStatus);
} catch (Exception e) {
log.error("分机号分配失败 memberId{}", memberId);
}
}
}
private List<ExtensionNumber> getNumbers(Integer minNumber, Integer maxNumber) {
List<ExtensionNumber> list = new ArrayList<>();
for (int i = minNumber; i <= maxNumber; i++) {
ExtensionNumber extensionNumber = new ExtensionNumber();
extensionNumber.setNumber(i);
list.add(extensionNumber);
}
return list;
}
}

@ -6,12 +6,15 @@ import cn.hutool.core.util.StrUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.feign.SourceClueClient;
import com.baiye.http.CommonResponse;
import com.baiye.modules.system.domain.Clue;
import com.baiye.modules.telemarkting.dao.AllCallInfoRepository;
import com.baiye.modules.telemarkting.dao.CallClueRepository;
import com.baiye.modules.telemarkting.dao.ExtensionUserRepository;
import com.baiye.modules.telemarkting.entity.AllCallInfo;
import com.baiye.modules.telemarkting.entity.CallClueInfo;
import com.baiye.modules.telemarkting.entity.dto.TelephoneCallReqDTO;
import com.baiye.modules.telemarkting.entity.dto.RollCallBackDTO;
import com.baiye.modules.telemarkting.httpRequest.RollCallReq;
import com.baiye.modules.telemarkting.service.RollCallService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -32,53 +35,61 @@ public class RollCallServiceImpl implements RollCallService {
private CallClueRepository callClueRepository;
@Resource
private SourceClueClient sourceClueClient;
/* @Resource
private RollCallReq rollCallReq;*/
@Resource
private RollCallReq rollCallReq;
@Resource
private ExtensionUserRepository extensionUserRepository;
@Override
public CommonResponse<Object> rollCallReq(TelephoneCallReqDTO telephoneCallReqDTO) {
String requestId = RandomUtil.randomString(10);
telephoneCallReqDTO.setRequestId(requestId);
// Clue body = sourceClueClient.queryDetails(Long.parseLong(doubleCallReq.getUserData())).getBody();
// if (ObjectUtil.isNull(body) || StrUtil.isEmpty(body.getNid())) {
// return CommonResponse.createByErrorMessage("未获取到号码");
// }
// doubleCallReq.setTelB(body.getNid());
telephoneCallReqDTO.setTelB("13003658692");
// TODO sessionId not setting
String sessionId = "";
log.info("=============================sessionId {}", sessionId);
if (StrUtil.isNotBlank(sessionId)) {
AllCallInfo allCallInfo = new AllCallInfo();
allCallInfo.setSessionId(sessionId);
allCallInfo.setRequestId(requestId);
allCallInfo.setClueId(Long.parseLong(telephoneCallReqDTO.getUserData()));
allCallInfo.setMemberId(telephoneCallReqDTO.getMemberId());
allCallInfo.setStatus(DefaultNumberConstants.ONE_NUMBER);
allCallInfo.setType(DefaultNumberConstants.ONE_NUMBER);
allCallInfo.setRecordFlag(DefaultNumberConstants.ZERO_NUMBER);
CallClueInfo clueInfo = new CallClueInfo();
clueInfo.setClueId(Long.parseLong(telephoneCallReqDTO.getUserData()));
clueInfo.setTeamId(telephoneCallReqDTO.getTeamId());
clueInfo.setMemberId(telephoneCallReqDTO.getMemberId());
clueInfo.setStatus(DefaultNumberConstants.ONE_NUMBER);
clueInfo.setTaskId(telephoneCallReqDTO.getTaskId());
//获取分机号
// Integer numberByMemberId = extensionUserRepository.findNumberByMemberId(telephoneCallReqDTO.getMemberId());
String numberByMemberId = "458000-458100";
if (numberByMemberId == null) {
return CommonResponse.createByErrorMessage("未配置分机号");
}
telephoneCallReqDTO.setTelA(String.valueOf(numberByMemberId));
//获取线索号
Clue body = sourceClueClient.queryDetails(Long.parseLong(telephoneCallReqDTO.getUserData())).getBody();
if (ObjectUtil.isNull(body) || StrUtil.isEmpty(body.getNid())) {
return CommonResponse.createByErrorMessage("未获取到号码");
}
telephoneCallReqDTO.setTelB(body.getNid());
String reqId = rollCallReq.startReq(telephoneCallReqDTO);
log.info("=============================reqId {}", reqId);
if (StrUtil.isNotBlank(reqId)) {
if (StrUtil.isNotBlank(reqId)) {
AllCallInfo allCallInfo = new AllCallInfo();
allCallInfo.setRequestId(requestId);
allCallInfo.setClueId(Long.parseLong(telephoneCallReqDTO.getUserData()));
allCallInfo.setMemberId(telephoneCallReqDTO.getMemberId());
allCallInfo.setStatus(DefaultNumberConstants.ONE_NUMBER);
allCallInfo.setType(DefaultNumberConstants.ONE_NUMBER);
allCallInfo.setRecordFlag(DefaultNumberConstants.ZERO_NUMBER);
allCallInfoRepository.save(allCallInfo);
callClueRepository.save(clueInfo);
} else {
return CommonResponse.createByError();
CallClueInfo clueInfo = new CallClueInfo();
clueInfo.setClueId(Long.parseLong(telephoneCallReqDTO.getUserData()));
clueInfo.setTeamId(telephoneCallReqDTO.getTeamId());
clueInfo.setMemberId(telephoneCallReqDTO.getMemberId());
clueInfo.setStatus(DefaultNumberConstants.ONE_NUMBER);
clueInfo.setTaskId(telephoneCallReqDTO.getTaskId());
allCallInfoRepository.save(allCallInfo);
callClueRepository.save(clueInfo);
} else {
return CommonResponse.createByError();
}
}
return CommonResponse.createBySuccess(sessionId);
return CommonResponse.createBySuccess(requestId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void rollCallBack(RollCallBackDTO rollCallBackDTO) {
String sessionId = rollCallBackDTO.getSessionid();
String reqId = rollCallBackDTO.getReqid();
AllCallInfo allCallInfo = allCallInfoRepository.findBySessionId(sessionId);
AllCallInfo allCallInfo = allCallInfoRepository.findByRequestId(reqId);
if (ObjectUtil.isNotEmpty(allCallInfo)) {
if (StrUtil.isBlank(rollCallBackDTO.getDuration())) {
//表示接通
@ -89,7 +100,6 @@ public class RollCallServiceImpl implements RollCallService {
allCallInfo.setRecordFlag(DefaultNumberConstants.ONE_NUMBER);
allCallInfo.setRecordFileDownloadUrl(rollCallBackDTO.getRecord_file_url());
}
allCallInfoRepository.save(allCallInfo);
}
}

@ -68,12 +68,6 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
log.info("=============================sessionId {}", sessionId);
if (StrUtil.isNotBlank(sessionId)) {
// DoubleCallInfo doubleCallInfo = new DoubleCallInfo();
// doubleCallInfo.setSessionId(sessionId);
// doubleCallInfo.setRequestId(requestId);
// doubleCallInfo.setClueId(Long.parseLong(doubleCallReq.getUserData()));
// doubleCallInfo.setMemberId(doubleCallReq.getMemberId());
// doubleCallInfo.setStatus(DefaultNumberConstants.ONE_NUMBER);
AllCallInfo allCallInfo = new AllCallInfo();
allCallInfo.setSessionId(sessionId);
allCallInfo.setRequestId(requestId);
@ -102,8 +96,6 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
String sessionId = doubleCallBack.getSessionId();
AllCallInfo allCallInfo = allCallInfoRepository.findBySessionId(sessionId);
if (ObjectUtil.isNotEmpty(allCallInfo)) {
// BeanUtil.copyProperties(doubleCallBack, doubleCallInfo);
// doubleCallRepository.save(doubleCallInfo);
allCallInfo.setDuration(doubleCallBack.getDuration());
allCallInfo.setRecordFlag(doubleCallBack.getRecordFlag());
allCallInfo.setRecordFileDownloadUrl(doubleCallBack.getRecordFileDownloadUrl());
@ -116,7 +108,6 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
public void doubleCallBackStatus(TelephoneCallBackStatusDTO doubleCallBackStatus) {
String sessionId = doubleCallBackStatus.getSessionId();
long userDate = Long.parseLong(doubleCallBackStatus.getUserData());
String flag = Objects.requireNonNull(CallStatusEnum.find(doubleCallBackStatus.getStatus())).getDescription();
if (CallStatusEnum.ANSWER.getDescription().equals(flag)) {
int status = CallStatusEnum.ANSWER.getValue();
@ -169,6 +160,8 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
allCallInfo.setClueId(originalNumber);
allCallInfo.setMemberId(doubleCallReq.getMemberId());
allCallInfo.setStatus(DefaultNumberConstants.ONE_NUMBER);
allCallInfo.setType(DefaultNumberConstants.THREE_NUMBER);
CallClueInfo clueInfo = new CallClueInfo();
clueInfo.setClueId(originalNumber);
clueInfo.setTeamId(doubleCallReq.getTeamId());

@ -6,15 +6,15 @@ import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.baiye.modules.report.entity.dto.UploadTaskDTO;
import com.baiye.modules.report.entity.vo.MemberInfoVO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -82,4 +82,46 @@ public class ExportExcelUtil {
}
}
public static void dynamicHeadWrite(HttpServletResponse response, List<LinkedList<Object>> linkedLists, List<String> heads, String taskName) {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("任务详情", "UTF-8") + ".xlsx");
EasyExcel.write(response.getOutputStream())
// 这里放入动态头
.head(head1(heads)).sheet(taskName)
// 当然这里数据也可以用 List<List<String>> 去传入
.doWrite(linkedLists);
} catch (Exception e) {
log.error(e.getMessage());
}
}
private static List<List<String>> head1(List<String> list) {
LinkedList<List<String>> headList = new LinkedList<List<String>>();
List<String> head0 = new ArrayList<>();
head0.add("线索名称");
List<String> head1 = new ArrayList<>();
head1.add("外呼次数");
List<String> head2 = new ArrayList<>();
head2.add("外呼接通量");
List<String> head3 = new ArrayList<>();
head3.add("外呼接通率");
List<String> head4 = new ArrayList<>();
head4.add("外呼总时长");
List<String> head5 = new ArrayList<>();
head5.add("平均通话时长");
headList.add(head0);
headList.add(head1);
headList.add(head2);
headList.add(head3);
headList.add(head4);
headList.add(head5);
for (String s : list) {
List<String> head = new ArrayList<>();
head.add(s);
headList.add(head);
}
return headList;
}
}

Loading…
Cancel
Save