Merge remote-tracking branch 'origin/master'

master
bynt 1 year ago
commit fbe13f5da5

@ -25,6 +25,7 @@ import com.baiye.modules.system.repository.UserRepository;
import com.baiye.modules.system.service.RoleService;
import com.baiye.modules.system.service.UserService;
import com.baiye.modules.telemarkting.dao.ExtensionUserRepository;
import com.baiye.modules.telemarkting.entity.ExtensionNumber;
import com.baiye.modules.telemarkting.service.ExtensionNumberService;
import com.baiye.util.*;
import com.google.common.collect.Lists;
@ -604,7 +605,9 @@ public class OrganizeServiceImpl implements OrganizeService {
Organize organize = organizeRepository.findById(organizeUser.getOrganizeId()).orElseGet(Organize::new);
if (organize.getCallMode() == 1) {
// (点呼)获取分机号
tel = String.valueOf(extensionNumberService.getExtension(userId).getNumber());
ExtensionNumber extension = extensionNumberService.getExtension(userId);
tel = String.valueOf(extension.getNumber());
callModeMap.put("sip", extension.getSip());
} else if (organize.getCallMode() == 2) {
Company company = companyRepository.findById(user.getCompanyId()).orElseGet(Company::new);
tel = company.getTelX();

@ -1,5 +1,6 @@
package com.baiye.modules.telemarkting.api;
import com.baiye.annotation.Inner;
import com.baiye.http.CommonResponse;
import com.baiye.modules.telemarkting.service.ExtensionNumberService;
import io.swagger.annotations.Api;
@ -50,4 +51,13 @@ public class ExtensionNumberController {
public CommonResponse<Object> queryExtensionDisplay(Long companyId) {
return CommonResponse.createBySuccess(extensionNumberService.queryExtensionDisplay(companyId));
}
@GetMapping("/sip")
@Inner(value = false)
public CommonResponse<Object> sip(@RequestParam("number") String number,
@RequestParam("name") String name)
{
return CommonResponse.createBySuccess(extensionNumberService.sip(number, name));
}
}

@ -1,9 +1,7 @@
package com.baiye.modules.telemarkting.api;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
@ -17,7 +15,6 @@ import com.baiye.modules.platform.service.OrganizeService;
import com.baiye.modules.system.service.UserService;
import com.baiye.modules.telemarkting.entity.dto.*;
import com.baiye.modules.telemarkting.service.TelephoneCallService;
import com.baiye.util.RedisUtils;
import com.baiye.util.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -44,35 +41,20 @@ import java.util.Date;
public class TelephoneCallController {
private final TelephoneCallService telephoneCallService;
private final OrganizeService organizeService;
private final CompanyService companyService;
private final UserService userService;
private final RedisUtils redisUtils;
@PostMapping("/telephone/req")
@ApiOperation("拨打电话")
public CommonResponse<TelephoneCallStopDTO> doubleCallReq(@Validated @RequestBody TelephoneCallReqDTO telephoneCallReqDTO) {
String key = "tele:" + telephoneCallReqDTO.getUserData();
if (redisUtils.get(key) != null) {
return CommonResponse.createByErrorMessage("请三分钟后再拨打此线索");
}
if (ObjectUtil.isEmpty(telephoneCallReqDTO)) {
return CommonResponse.createByError();
}
//判断账号是否到期
Long currentUserId = SecurityUtils.getCurrentUserId();
Date expirationTime = userService.findExpirationTimeByUserId(currentUserId);
log.info("============== the expirationTime as {} =============", expirationTime);
Date expirationTime = userService.findExpirationTimeByUserId(SecurityUtils.getCurrentUserId());
if (ObjectUtil.isNull(expirationTime)
|| DateUtil.compare(expirationTime, DateUtil.date()) < DefaultNumberConstants.ZERO_NUMBER) {
return CommonResponse.createByErrorMessage("您的账号已到期,请续费后使用");
}
Long companyId = SecurityUtils.getCompanyId();
if (companyId != null) {
Organize organize;
if (telephoneCallReqDTO.getTeamId() == null) {
organize = organizeService.getOrganizeByUserId(telephoneCallReqDTO.getMemberId());
@ -80,23 +62,27 @@ public class TelephoneCallController {
} else {
organize = organizeService.findByOrganizeId(telephoneCallReqDTO.getTeamId());
}
Company byId = companyService.findById(companyId);
if (organize != null && byId != null) {
//TODO 检查余额
if (byId.getUserBalance() == null || byId.getUserBalance() <= 0) {
Company company = companyService.findById(companyId);
if (ObjectUtil.isNull(organize) || ObjectUtil.isNull(company)) {
return CommonResponse.createByErrorMessage("缺失小组信息或公司信息");
}
if (company.getUserBalance() == null || company.getUserBalance() <= 0) {
return CommonResponse.createByErrorMessage("余额不足,请充值后使用");
}
if (organize.getCallMode() != null) {
if (organize.getCallMode() == null) {
return CommonResponse.createByErrorMessage("请指定呼叫方式后使用");
}
//呼叫方式0:双呼 1:点呼 2:AXB
switch (organize.getCallMode()) {
case DefaultNumberConstants.ZERO_NUMBER:
telephoneCallReqDTO.setCompanyName(byId.getCompanyName().trim());
telephoneCallReqDTO.setCompanyName(company.getCompanyName().trim());
return telephoneCallService.doubleCallReq(telephoneCallReqDTO, companyId);
case DefaultNumberConstants.TWO_NUMBER:
if (StringUtils.isBlank(byId.getXGroup()) || StringUtils.isBlank(byId.getTelX())) {
if (StringUtils.isBlank(company.getXGroup()) || StringUtils.isBlank(company.getTelX())) {
throw new BadRequestException(ResponseCode.AXB_CONFIGURATION_ERROR.getDesc());
}
telephoneCallReqDTO.setTelX(byId.getTelX());
telephoneCallReqDTO.setXGroup(byId.getXGroup());
telephoneCallReqDTO.setTelX(company.getTelX());
telephoneCallReqDTO.setXGroup(company.getXGroup());
return telephoneCallService.axbDialNumber(telephoneCallReqDTO, companyId);
case DefaultNumberConstants.ONE_NUMBER:
return telephoneCallService.rollCallReq(telephoneCallReqDTO, companyId);
@ -104,13 +90,6 @@ public class TelephoneCallController {
return CommonResponse.createByErrorMessage("未配置呼叫");
}
}
}
}
redisUtils.set(key, RandomUtil.randomString(4), 60);
return CommonResponse.createByError();
}
@PostMapping("/back/cdrUrl")
@ApiOperation("双呼系统回调话单")
@ -168,11 +147,9 @@ public class TelephoneCallController {
if (ObjectUtil.isEmpty(rollCallBackDTO) || StrUtil.isEmpty(rollCallBackDTO.getSessionid())) {
return CommonResponse.createByErrorMessage("参数为空");
}
log.info("点呼回调:{}", rollCallBackDTO);
telephoneCallService.rollCallBack(rollCallBackDTO);
} catch (Exception e) {
log.error("点呼回调话单错误 参数 {}", json);
log.error("点呼回调话单错误,数据解析错误 {}", e.getMessage());
log.error("点呼回调话单错误 参数 {},错误:{}", json, e.getMessage());
return CommonResponse.createByError();
}
return CommonResponse.createBySuccess();

@ -32,7 +32,15 @@ public interface ExtensionUserRepository extends JpaRepository<ExtensionUser, Lo
@Modifying
@Query(value = "delete from tb_extension_user where member_id in ?1", nativeQuery = true)
int deleteByMemberId(List<Long> userIds);
/**
*
*
* @param numbers
* @return
*/
@Modifying
@Query(value = "delete from tb_extension_user where number in ?1", nativeQuery = true)
int deleteByNumbers(List<Integer> numbers);
/**
* id
*

@ -50,4 +50,9 @@ public class ExtensionNumber implements Serializable {
@ApiModelProperty(value = "抖音外显号")
@Transient
private Long dyDisplay;
@Column(name = "sip")
@ApiModelProperty(value = "sip")
private String sip;
}

@ -0,0 +1,46 @@
package com.baiye.modules.telemarkting.httpRequest;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author wjt
* @date 2023/3/31
*/
@Slf4j
@Component
public class NumberSipReq {
private static final String REQUEST_ID = "test";
private static final String URL = "https://ax.hzdaba.cn/v2/Accounts/dbby_hangzhoubaiyehl/Ex/getExtension";
public String req(String number,String name) {
Map<String, String> map = new HashMap<>(3);
map.put("requestId", REQUEST_ID);
map.put("company_name", name);
map.put("extension_number", number);
HttpResponse httpResponse = sendReq(JSONUtil.toJsonStr(map));
JSONObject jsonObject = JSONUtil.parseObj(httpResponse.body());
log.info("获取的密码 {}", httpResponse.body());
if (String.valueOf(DefaultNumberConstants.ZERO_NUMBER).equals(jsonObject.getStr("result"))) {
return jsonObject.getStr("password");
} else {
log.error("请求分机号sip失败,{}", jsonObject.getStr("reason"));
throw new BadRequestException("导入分机号失败");
}
}
private HttpResponse sendReq(String json) {
return HttpRequest.post(URL).body(json).execute();
}
}

@ -60,7 +60,7 @@ public class RollCallReq {
rollCallSystemDTO.setCdr_url(cdrUrl);
rollCallSystemDTO.setDisplay_callee(String.valueOf(doubleCallReq.getDisplay()));
rollCallSystemDTO.setDisplay_caller(String.valueOf(doubleCallReq.getDisplay()));
log.info("点呼请求对象{}", BeanUtil.beanToMap(rollCallSystemDTO));
log.info("点呼请求参数{}", BeanUtil.beanToMap(rollCallSystemDTO));
//设置重试机制
int count = 0;
@ -68,7 +68,6 @@ public class RollCallReq {
while (count <= flag) {
try {
String httpResponse = sendCallReq(BeanUtil.beanToMap(rollCallSystemDTO), reqUrl, authorization);
log.info("点呼返回值为 {}", httpResponse);
RollCallResponse doubleCallResponse = JSONUtil.toBean(httpResponse, RollCallResponse.class);
if (String.valueOf
(DefaultNumberConstants.ZERO_NUMBER)
@ -104,7 +103,6 @@ public class RollCallReq {
jsonObject.putOpt("body", json);
HttpResponse httpResponse = HttpRequest.post(stopUrl).body(JSONUtil.toJsonPrettyStr(jsonObject)).execute();
if (httpResponse.isOk()) {
log.info("请求挂断成功,返回值:{}", httpResponse.body());
return Boolean.TRUE;
} else {
count++;

@ -16,6 +16,8 @@ public interface ExtensionNumberService {
ExtensionNumber getExtension(Long memberId);
String sip(String number, String name);
/**
*
*

@ -3,13 +3,16 @@ package com.baiye.modules.telemarkting.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.SerializeUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.exception.BadRequestException;
import com.baiye.http.CommonResponse;
import com.baiye.modules.platform.domain.Company;
import com.baiye.modules.platform.domain.Organize;
import com.baiye.modules.platform.repository.OrganizeRepository;
import com.baiye.modules.platform.service.CompanyService;
import com.baiye.modules.system.domain.User;
import com.baiye.modules.system.repository.UserRepository;
import com.baiye.modules.telemarkting.dao.ExtensionDisplayRepository;
@ -18,6 +21,7 @@ import com.baiye.modules.telemarkting.dao.ExtensionUserRepository;
import com.baiye.modules.telemarkting.entity.ExtensionDisplay;
import com.baiye.modules.telemarkting.entity.ExtensionNumber;
import com.baiye.modules.telemarkting.entity.ExtensionUser;
import com.baiye.modules.telemarkting.httpRequest.NumberSipReq;
import com.baiye.modules.telemarkting.service.ExtensionNumberService;
import com.baiye.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
@ -48,6 +52,16 @@ public class ExtensionNumberServiceImpl implements ExtensionNumberService {
private UserRepository userRepository;
@Resource
private OrganizeRepository organizeRepository;
@Resource
private NumberSipReq numberSipReq;
@Resource
private CompanyService companyService;
@Override
public String sip(String number,String name) {
String sip = numberSipReq.req(number,name);
return sip;
}
@Override
@Transactional(rollbackFor = Exception.class)
@ -80,20 +94,29 @@ public class ExtensionNumberServiceImpl implements ExtensionNumberService {
//解析保存分机号
if (ObjectUtil.isNotEmpty(file) && file.getSize() > 0) {
List<ExtensionNumber> list = new ArrayList<>();
List<Integer> numbers = new ArrayList<>();
try {
int lastIndexOf = Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf(".");
String nameFormat = file.getOriginalFilename().substring(lastIndexOf + 1);
if ("xlsx".equals(nameFormat) || "xls".equals(nameFormat)) {
ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
List<List<Object>> read = reader.read(0, reader.getRowCount());
Company company = companyService.findById(companyId);
for (List<Object> objects : read) {
String number = String.valueOf(objects.get(0));
ExtensionNumber extensionNumber = new ExtensionNumber();
extensionNumber.setNumber(Integer.valueOf(number));
extensionNumber.setCompanyId(companyId);
String sip = numberSipReq.req(number,company.getCompanyName());
extensionNumber.setSip(sip);
list.add(extensionNumber);
numbers.add(Integer.valueOf(number));
}
}
//删除以前的旧绑定关系
extensionUserRepository.deleteByNumbers(numbers);
extensionNumberRepository.saveAll(list);
} catch (Exception e) {
log.error("读取文件错误:{}", e.getMessage());
@ -131,7 +154,7 @@ public class ExtensionNumberServiceImpl implements ExtensionNumberService {
//查一个分机号
Integer idByStatus = extensionNumberRepository.findIdByStatusAndCompanyId(DefaultNumberConstants.ZERO_NUMBER, companyId);
if (idByStatus == null || idByStatus == 0) {
log.error("可分配的分机号不足,请联系管理员");
log.error("可分配的分机号不足,请联系管理员 公司id={}", companyId);
throw new BadRequestException("可分配的分机号不足,请联系管理员");
}
ExtensionUser extensionUser = new ExtensionUser();
@ -182,7 +205,9 @@ public class ExtensionNumberServiceImpl implements ExtensionNumberService {
extensionUserRepository.deleteByMemberId(userId);
} else {
int i = extensionUserRepository.deleteByMemberId(replaceUserId);
if (i > 0) extensionNumberRepository.updateExtensionNumber(0, replaceUserId);
if (i > 0) {
extensionNumberRepository.updateExtensionNumber(0, replaceUserId);
}
extensionUserRepository.updateByNumber(userId, replaceUserId);
}
}
@ -216,7 +241,9 @@ public class ExtensionNumberServiceImpl implements ExtensionNumberService {
extensionNumberRepository.updateStatusById(0, extensionUser.getNumber());
}
} else {
if (organize.getCallMode() == 1) this.assignExtensionNum(organizeId, userId);
if (organize.getCallMode() == 1) {
this.assignExtensionNum(organizeId, userId);
}
}
}
}

@ -44,7 +44,6 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
@Resource
private AxbRequest axbRequest;
@Resource
private DoubleCallReq doubleCallReq;
@Resource
@ -56,7 +55,7 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
@Resource
private SourceClueClient sourceClueClient;
@Resource
private ExtensionNumberRepository extensionNumberRepository;
private ExtensionUserRepository extensionUserRepository;
@Resource
private ExtensionDisplayRepository extensionDisplayRepository;
@Resource
@ -206,58 +205,71 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
telephoneCallReqDTO.setRequestId(requestId);
if (telephoneCallReqDTO.getDisplay() == null || telephoneCallReqDTO.getTelA() == null) {
//获取分机号
//TODO 新需求,外显号多个
ExtensionNumber extensionNumber = extensionNumberRepository.selectByMemberId(telephoneCallReqDTO.getMemberId());
if (extensionNumber == null) {
log.error("未配置分机号");
return CommonResponse.createByErrorMessage("未配置分机号");
Integer number = extensionUserRepository.findNumberByMemberId(telephoneCallReqDTO.getMemberId());
if (number == null) {
return CommonResponse.createByErrorMessage("未分配分机号");
}
ExtensionDisplay extensionDisplay = extensionDisplayRepository.findExtensionDisplayByCompanyId(extensionNumber.getCompanyId());
ExtensionDisplay extensionDisplay = extensionDisplayRepository.findExtensionDisplayByCompanyId(companyId);
if (ObjectUtil.isNull(extensionDisplay)) {
return CommonResponse.createByErrorMessage("未配置去显号");
}
telephoneCallReqDTO.setTelA(String.valueOf(extensionNumber.getNumber()));
telephoneCallReqDTO.setTelA(String.valueOf(number));
//获取去显号
Long display;
if (telephoneCallReqDTO.getClueType() == DefaultNumberConstants.THREE_NUMBER) {
switch (telephoneCallReqDTO.getClueType()) {
case DefaultNumberConstants.THREE_NUMBER:
if (extensionDisplay.getDyDisplay() == null) {
return CommonResponse.createByErrorMessage("未配置抖音去显号");
}
display = extensionDisplay.getDyDisplay();
} else if (telephoneCallReqDTO.getClueType() == DefaultNumberConstants.FOUR_NUMBER) {
break;
case DefaultNumberConstants.FOUR_NUMBER:
if (extensionDisplay.getDeliveryDisplay() == null) {
return CommonResponse.createByErrorMessage("未配置投流去显号");
}
display = extensionDisplay.getDeliveryDisplay();
} else if (telephoneCallReqDTO.getClueType() == DefaultNumberConstants.FIVE_NUMBER) {
break;
case DefaultNumberConstants.FIVE_NUMBER:
if (extensionDisplay.getTokerDisplay() == null) {
return CommonResponse.createByErrorMessage("未配置拓客去显号");
}
display = extensionDisplay.getTokerDisplay();
} else {
break;
default:
if (extensionDisplay.getDisplay() == null) {
return CommonResponse.createByErrorMessage("未配置去显号");
}
display = extensionDisplay.getDisplay();
}
//设置去显号
telephoneCallReqDTO.setDisplay(display);
}
//获取线索号
//获取被叫号
Clue body;
try {
body = sourceClueClient.queryDetails(Long.parseLong(telephoneCallReqDTO.getUserData())).getBody();
} catch (Exception e) {
log.error("Method 【rollCallReq】query clue error{},time:{} ", e.getMessage(), DateUtil.now());
throw new BadRequestException("查询线索错误");
log.error("获取被叫号错误{},time:{} ", e.getMessage(), DateUtil.now());
throw new BadRequestException("呼叫失败");
}
if (ObjectUtil.isNull(body) || StrUtil.isEmpty(body.getNid())) {
log.error("未获取到号码");
return CommonResponse.createByErrorMessage("未获取到号码");
}
telephoneCallReqDTO.setTelB(body.getNid());
telephoneCallReqDTO.setTelB("474" + telephoneCallReqDTO.getDisplay() + body.getNid());
//请求呼叫
String reqId = rollCallReq.startReq(telephoneCallReqDTO);
//保存呼叫记录
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());
clueInfo.setCompanyId(companyId);
callClueRepository.save(clueInfo);
//保存呼叫详情
AllCallInfo allCallInfo = new AllCallInfo();
allCallInfo.setSessionId(requestId);
allCallInfo.setRequestId(requestId);
@ -267,16 +279,8 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
allCallInfo.setStatus(DefaultNumberConstants.ONE_NUMBER);
allCallInfo.setType(DefaultNumberConstants.TWO_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());
clueInfo.setCompanyId(companyId);
allCallInfoRepository.save(allCallInfo);
callClueRepository.save(clueInfo);
TelephoneCallStopDTO telephoneCallStopDTO = new TelephoneCallStopDTO();
telephoneCallStopDTO.setSessionid(reqId);
telephoneCallStopDTO.setCallId(requestId);
@ -303,20 +307,21 @@ public class TelephoneCallServiceImpl implements TelephoneCallService {
String otherLeg = rollCallBackDTO.getOtherLeg();
AllCallInfo allCallInfo = allCallInfoRepository.findBySessionId(otherLeg);
// int status = DefaultNumberConstants.ONE_NUMBER;
if (ObjectUtil.isNotEmpty(allCallInfo)) {
//相同说明是分机号的回调
if (sessionId.equals(otherLeg) && StrUtil.isNotBlank(rollCallBackDTO.getRecord_file_url())) {
log.info("分机回调-点呼otherLeg:{},详情:{}", otherLeg, rollCallBackDTO);
allCallInfoRepository.updateByRecord(DefaultNumberConstants.ONE_NUMBER, rollCallBackDTO.getRecord_file_url(), allCallInfo.getId());
} else {
log.info("被叫回调-点呼otherLeg:{},详情:{}", otherLeg, rollCallBackDTO);
//拨打线索号的回调
if (StrUtil.isNotBlank(rollCallBackDTO.getCallee_answer_time())) {
//表示接通
//表示接通,更新线索状态
callClueRepository.updateByStatus(DefaultNumberConstants.TWO_NUMBER, allCallInfo.getClueId());
allCallInfoRepository.updateByDurationAndStatus(DefaultNumberConstants.TWO_NUMBER, Integer.valueOf(rollCallBackDTO.getDuration()), allCallInfo.getId());
//更新资源通话状态
CompletableFuture.runAsync(() -> updateSourceCallStatus(allCallInfo.getClueId(), DefaultNumberConstants.TWO_NUMBER, allCallInfo.getClueType()));
//TODO 实时扣除话费
//实时扣除话费
callCostCount(allCallInfo.getMemberId(), allCallInfo.getClueId(), allCallInfo.getClueType(), Integer.valueOf(rollCallBackDTO.getDuration()), 2);
} else {
//更新资源通话状态

Loading…
Cancel
Save