Changes
parent
c5ca515e7d
commit
477ca4a773
@ -0,0 +1,16 @@
|
||||
package com.baiye.exception;
|
||||
|
||||
import com.dangdang.ddframe.job.executor.handler.JobExceptionHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/15
|
||||
*/
|
||||
@Slf4j
|
||||
public class ElasticException implements JobExceptionHandler {
|
||||
@Override
|
||||
public void handleException(String s, Throwable throwable) {
|
||||
log.info("elastic-job 捕获全局异常,任务名:{},异常原因:{}", s, throwable.getMessage());
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.baiye.model.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/14
|
||||
*/
|
||||
@MappedSuperclass
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
@Data
|
||||
public class BaseCallClueInfo {
|
||||
@Column(name = "team_id")
|
||||
private Long teamId;
|
||||
@Column(name = "member_id")
|
||||
private Long memberId;
|
||||
@Column(name = "status")
|
||||
private Integer status;
|
||||
@Column(name = "task_id")
|
||||
private Long taskId;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.baiye.model.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/10
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum CallStatusEnum {
|
||||
/**
|
||||
* 拨打
|
||||
*/
|
||||
CALL(0, "call"),
|
||||
/**
|
||||
* 响铃
|
||||
*/
|
||||
ALERT(1, "alert"),
|
||||
/**
|
||||
* 接通
|
||||
*/
|
||||
ANSWER(2, "answer"),
|
||||
/**
|
||||
* 挂断
|
||||
*/
|
||||
HANGUP(3, "hangup");
|
||||
private final int value;
|
||||
private final String description;
|
||||
|
||||
public static CallStatusEnum find(String val) {
|
||||
for (CallStatusEnum dataScopeEnum : CallStatusEnum.values()) {
|
||||
if (val.equals(dataScopeEnum.getDescription())) {
|
||||
return dataScopeEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baiye.modules.telemarkting.dao;
|
||||
|
||||
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.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/13
|
||||
*/
|
||||
@Repository
|
||||
public interface CallClueRepository extends JpaRepository<CallClueInfo, Long>, JpaSpecificationExecutor<CallClueInfo> {
|
||||
/**
|
||||
* 主键查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
CallClueInfo findByClueId(Long id);
|
||||
|
||||
/**
|
||||
* 按条件查询
|
||||
*
|
||||
* @param memberId
|
||||
* @return
|
||||
*/
|
||||
@Query("select d from CallClueInfo d where d.memberId=?1 ")
|
||||
List<CallClueInfo> selectByMember(Long memberId);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baiye.modules.telemarkting.dao;
|
||||
|
||||
import com.baiye.modules.telemarkting.entity.DoubleCallInfo;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/06
|
||||
*/
|
||||
@Repository
|
||||
public interface DoubleCallRepository extends JpaRepository<DoubleCallInfo, Long>, JpaSpecificationExecutor<DoubleCallInfo> {
|
||||
/**
|
||||
* 根据id查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
DoubleCallInfo findById(String id);
|
||||
|
||||
/**
|
||||
* 按条件查询
|
||||
*
|
||||
* @param memberId
|
||||
* @return
|
||||
*/
|
||||
@Query("select d from DoubleCallInfo d where d.memberId=?1 ")
|
||||
List<DoubleCallInfo> selectByMemberAndStatus(Long memberId);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baiye.modules.telemarkting.entity;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import com.baiye.model.entity.BaseCallClueInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
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 wjt
|
||||
* @date 2021/12/13
|
||||
* 线索中间表
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "tb_call_clue")
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
public class CallClueInfo extends BaseCallClueInfo implements Serializable {
|
||||
private static final long serialVersionUID = -2063303635710762496L;
|
||||
|
||||
@Id
|
||||
@Column(name = "clue_id")
|
||||
private Long clueId;
|
||||
@LastModifiedDate
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.baiye.modules.telemarkting.entity.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/02
|
||||
* 话单回调接收
|
||||
*/
|
||||
@Data
|
||||
public class DoubleCallBackDTO {
|
||||
private Integer direction;
|
||||
private String spId;
|
||||
private String appKey;
|
||||
private String icid;
|
||||
private String bindNum;
|
||||
private String sessionId;
|
||||
private String callerNum;
|
||||
private String calleeNum;
|
||||
private String fwdDisplayNum;
|
||||
private String fwdDstNum;
|
||||
private String fwdStartTime;
|
||||
private String fwdAlertingTime;
|
||||
private String fwdAnswerTime;
|
||||
private String callEndTime;
|
||||
private Integer fwdUnaswRsn;
|
||||
private Integer ulFailReason;
|
||||
private Integer sipStatusCode;
|
||||
private String callOutStartTime;
|
||||
private String callOutAlertingTime;
|
||||
private String callOutAnswerTime;
|
||||
private Integer callOutUnaswRsn;
|
||||
private Integer duration;
|
||||
private Integer fee_duration;
|
||||
private String price;
|
||||
private String fee;
|
||||
|
||||
private Integer recordFlag;
|
||||
private Integer recordStartTime;
|
||||
private Integer ttsPlayTimes;
|
||||
private String ttsTransDuration;
|
||||
private String serviceType;
|
||||
private String hostName;
|
||||
private String userData;
|
||||
private String recordFileDownloadUrl;
|
||||
private String bindingId;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.baiye.modules.telemarkting.entity.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/06
|
||||
* 状态回调
|
||||
*/
|
||||
@Data
|
||||
public class DoubleCallBackStatusDTO {
|
||||
private String status;
|
||||
private String callId;
|
||||
private String sessionId;
|
||||
private String userData;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baiye.modules.telemarkting.entity.dto;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/02
|
||||
* 前段请求接通双呼的参数类
|
||||
*/
|
||||
@Data
|
||||
public class DoubleCallReqDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8037829549747968861L;
|
||||
/**
|
||||
* 真实主叫
|
||||
*/
|
||||
private String telA;
|
||||
/**
|
||||
* 真实被叫
|
||||
*/
|
||||
private String telB;
|
||||
private String requestId;
|
||||
/**
|
||||
* 线索id
|
||||
*/
|
||||
private String userData;
|
||||
private Long teamId;
|
||||
private Long memberId;
|
||||
private Long taskId;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.baiye.modules.telemarkting.entity.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/14
|
||||
*/
|
||||
@Data
|
||||
public class DoubleCallSystemDTO {
|
||||
private String appid;
|
||||
private String requestId;
|
||||
private String telA;
|
||||
private String telB;
|
||||
private String companyName;
|
||||
private String userData;
|
||||
private String cdrUrl;
|
||||
private String statusUrl;
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package com.baiye.modules.telemarkting.httpRequest;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallReqDTO;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallSystemDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.companyName}")
|
||||
private String companyName;
|
||||
@Value("${double.call.cdrUrl}")
|
||||
private String cdrUrl;
|
||||
@Value("${double.call.statusUrl}")
|
||||
private String statusUrl;
|
||||
|
||||
public String startReq(DoubleCallReqDTO doubleCallReq) {
|
||||
log.info("=======================doubleCallReq start in {}", DateUtil.date());
|
||||
return reqTask(doubleCallReq);
|
||||
}
|
||||
|
||||
private String reqTask(DoubleCallReqDTO doubleCallReq) {
|
||||
DoubleCallSystemDTO doubleCallSystemDTO = new DoubleCallSystemDTO();
|
||||
BeanUtil.copyProperties(doubleCallReq, doubleCallSystemDTO);
|
||||
doubleCallSystemDTO.setAppid(appid);
|
||||
doubleCallSystemDTO.setCompanyName(companyName);
|
||||
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("请求成功");
|
||||
// log.info("返回值:{}", httpResponse.body());
|
||||
// JSONObject result = JSONUtil.parseObj(httpResponse.body());
|
||||
// return result.get("sessionId").toString();
|
||||
// } else {
|
||||
// count++;
|
||||
// log.error("请求失败,response==={}", httpResponse.body());
|
||||
// }
|
||||
return RandomUtil.randomString(6);
|
||||
}
|
||||
log.info("=======================doubleCallReq end in {}", DateUtil.date());
|
||||
return null;
|
||||
}
|
||||
|
||||
public Boolean stopReq(String sessionId) {
|
||||
log.info("=======================stopReq start in {}", DateUtil.date());
|
||||
return stopTask(sessionId);
|
||||
}
|
||||
|
||||
private Boolean stopTask(String sessionId) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.putOpt("sessionId", sessionId);
|
||||
jsonObject.putOpt("callId", "");
|
||||
int count = 0;
|
||||
int flag = 3;
|
||||
while (count <= flag) {
|
||||
log.info("请求对象:{}", jsonObject);
|
||||
HttpResponse httpResponse = sendCallReq(jsonObject.toString(), stopUrl);
|
||||
if (httpResponse.isOk()) {
|
||||
log.info("请求成功");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();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.baiye.modules.telemarkting.service;
|
||||
|
||||
import com.baiye.http.CommonResponse;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallBackDTO;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallBackStatusDTO;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallReqDTO;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/14
|
||||
*/
|
||||
public interface DoubleCallService {
|
||||
/**
|
||||
* 双呼请求
|
||||
*
|
||||
* @param doubleCallReq
|
||||
* @return
|
||||
*/
|
||||
CommonResponse<Object> doubleCallReq(DoubleCallReqDTO doubleCallReq);
|
||||
|
||||
/**
|
||||
* 回调话单
|
||||
*
|
||||
* @param doubleCallBack
|
||||
*/
|
||||
void doubleCallBack(DoubleCallBackDTO doubleCallBack);
|
||||
|
||||
/**
|
||||
* 回调状态
|
||||
*
|
||||
* @param doubleCallBackStatus
|
||||
*/
|
||||
void doubleCallBackStatus(DoubleCallBackStatusDTO doubleCallBackStatus);
|
||||
|
||||
/**
|
||||
* 停止通话
|
||||
*
|
||||
* @param sessionId
|
||||
* @return
|
||||
*/
|
||||
CommonResponse<Object> doubleCallStop(String sessionId);
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package com.baiye.modules.telemarkting.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baiye.http.CommonResponse;
|
||||
import com.baiye.model.enums.CallStatusEnum;
|
||||
import com.baiye.modules.telemarkting.dao.CallClueRepository;
|
||||
import com.baiye.modules.telemarkting.dao.DoubleCallRepository;
|
||||
import com.baiye.modules.telemarkting.entity.CallClueInfo;
|
||||
import com.baiye.modules.telemarkting.entity.DoubleCallInfo;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallBackDTO;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallBackStatusDTO;
|
||||
import com.baiye.modules.telemarkting.entity.dto.DoubleCallReqDTO;
|
||||
import com.baiye.modules.telemarkting.httpRequest.CallReq;
|
||||
import com.baiye.modules.telemarkting.service.DoubleCallService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/14
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class DoubleCallServiceImpl implements DoubleCallService {
|
||||
@Resource
|
||||
private CallReq callReq;
|
||||
@Resource
|
||||
private DoubleCallRepository doubleCallRepository;
|
||||
@Resource
|
||||
private CallClueRepository callClueRepository;
|
||||
|
||||
@Override
|
||||
public CommonResponse<Object> doubleCallReq(DoubleCallReqDTO doubleCallReq) {
|
||||
String requestId = RandomUtil.randomString(10);
|
||||
doubleCallReq.setRequestId(requestId);
|
||||
String sessionId = callReq.startReq(doubleCallReq);
|
||||
|
||||
if (StrUtil.isNotBlank(sessionId)) {
|
||||
DoubleCallInfo doubleCallInfo = new DoubleCallInfo();
|
||||
doubleCallInfo.setId(sessionId);
|
||||
doubleCallInfo.setRequestId(requestId);
|
||||
doubleCallInfo.setClueId(doubleCallReq.getUserData());
|
||||
doubleCallInfo.setMemberId(doubleCallReq.getMemberId());
|
||||
|
||||
CallClueInfo clueInfo = new CallClueInfo();
|
||||
clueInfo.setClueId(Long.parseLong(doubleCallReq.getUserData()));
|
||||
clueInfo.setTeamId(doubleCallReq.getTeamId());
|
||||
clueInfo.setMemberId(doubleCallReq.getMemberId());
|
||||
clueInfo.setStatus(CallStatusEnum.CALL.getValue());
|
||||
clueInfo.setTaskId(doubleCallReq.getTaskId());
|
||||
|
||||
doubleCallRepository.save(doubleCallInfo);
|
||||
callClueRepository.save(clueInfo);
|
||||
} else {
|
||||
return CommonResponse.createByError();
|
||||
}
|
||||
return CommonResponse.createBySuccess(sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doubleCallBack(DoubleCallBackDTO doubleCallBack) {
|
||||
String sessionId = doubleCallBack.getSessionId();
|
||||
DoubleCallInfo doubleCallInfo = doubleCallRepository.findById(sessionId);
|
||||
if (ObjectUtil.isNotEmpty(doubleCallInfo)) {
|
||||
BeanUtil.copyProperties(doubleCallBack, doubleCallInfo);
|
||||
log.info("===================话单回调信息: {}", doubleCallInfo);
|
||||
doubleCallRepository.save(doubleCallInfo);
|
||||
}
|
||||
log.info("===========回调话单 未查询到会话信息 id:{}", sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doubleCallBackStatus(DoubleCallBackStatusDTO doubleCallBackStatus) {
|
||||
String sessionId = doubleCallBackStatus.getSessionId();
|
||||
long userDate = Long.parseLong(doubleCallBackStatus.getUserData());
|
||||
CallClueInfo clueInfo = callClueRepository.findByClueId(userDate);
|
||||
if (ObjectUtil.isNotEmpty(clueInfo)) {
|
||||
clueInfo.setStatus(Objects.requireNonNull(CallStatusEnum.find(doubleCallBackStatus.getStatus())).getValue());
|
||||
}
|
||||
log.info("===========回调状态 未查询到会话信息 id:{}", sessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<Object> doubleCallStop(String sessionId) {
|
||||
if (callReq.stopReq(sessionId)) {
|
||||
return CommonResponse.createBySuccess();
|
||||
}
|
||||
return CommonResponse.createByError();
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package com.baiye.api;
|
||||
|
||||
import com.baiye.entity.Job;
|
||||
import com.baiye.entity.JobBriefInfo;
|
||||
import com.baiye.service.ElasticJobService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/11/26
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/job")
|
||||
public class ElasticJobController {
|
||||
@Resource
|
||||
private ElasticJobService jobService;
|
||||
|
||||
/**
|
||||
* 注册新任务
|
||||
*
|
||||
* @param job
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public void addJob(@RequestBody Job job) {
|
||||
log.info("++++++++++++++++++++++++++++++++++++++++++++++++注册定时任务:{}", job.toString());
|
||||
jobService.addJob(job);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除任务
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
@GetMapping("/remove")
|
||||
public void remove(String jobName) {
|
||||
log.info("=+++++++++++++++++++++++++++++++++++++++++++++++删除定时任务:{}", jobName);
|
||||
jobService.removeJob(jobName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务信息
|
||||
*
|
||||
* @param jobName
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/info")
|
||||
public Job getJobDetails(String jobName) {
|
||||
return jobService.getJobDetail(jobName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有任务的信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/all")
|
||||
public List<JobBriefInfo> getAllJobsDetails() {
|
||||
return jobService.getAllJobsDetails();
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
public void updateJob(@RequestBody Job job) {
|
||||
log.info("++++++++++++++++++++++++++++++++++++++++++++++++修改任务:{}", job.toString());
|
||||
jobService.updateJob(job);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动触发
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
@GetMapping("/trigger")
|
||||
public void trigger(String jobName) {
|
||||
jobService.trigger(jobName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动失效
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
@GetMapping("/disable")
|
||||
public void disable(String jobName) {
|
||||
jobService.disable(jobName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动生效
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
@GetMapping("/enable")
|
||||
public void enable(String jobName) {
|
||||
jobService.enable(jobName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 终止
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
@GetMapping("/shutdown")
|
||||
public void shutdown(String jobName) {
|
||||
jobService.shutdown(jobName);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baiye.api;
|
||||
|
||||
import com.baiye.entity.vo.MemberInfoVO;
|
||||
import com.baiye.http.CommonResponse;
|
||||
import com.baiye.service.ReportService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 wjt
|
||||
* @date 2021/12/14
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
@Slf4j
|
||||
public class ReportController {
|
||||
@Resource
|
||||
private ReportService reportService;
|
||||
|
||||
@GetMapping("/report/member")
|
||||
public CommonResponse<Object> getMemberReport(Long memberId) {
|
||||
MemberInfoVO memberReport = reportService.getMemberReport(memberId);
|
||||
return CommonResponse.createBySuccess(memberReport);
|
||||
}
|
||||
|
||||
@GetMapping("/report/manager")
|
||||
public CommonResponse<Object> getReportHour() {
|
||||
reportService.reportHour();
|
||||
return CommonResponse.createBySuccess();
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.baiye.config;
|
||||
|
||||
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration;
|
||||
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(ZookeeperProperties.class)
|
||||
public class JobParserAutoConfiguration {
|
||||
|
||||
@Resource
|
||||
private ZookeeperProperties zookeeperProperties;
|
||||
|
||||
/**
|
||||
* 初始化Zookeeper注册中心
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean(initMethod = "init")
|
||||
public ZookeeperRegistryCenter zookeeperRegistryCenter() {
|
||||
ZookeeperConfiguration zkConfig = new ZookeeperConfiguration(zookeeperProperties.getServerLists(),
|
||||
zookeeperProperties.getNamespace());
|
||||
zkConfig.setBaseSleepTimeMilliseconds(zookeeperProperties.getBaseSleepTimeMilliseconds());
|
||||
zkConfig.setConnectionTimeoutMilliseconds(zookeeperProperties.getConnectionTimeoutMilliseconds());
|
||||
zkConfig.setDigest(zookeeperProperties.getDigest());
|
||||
zkConfig.setMaxRetries(zookeeperProperties.getMaxRetries());
|
||||
zkConfig.setMaxSleepTimeMilliseconds(zookeeperProperties.getMaxSleepTimeMilliseconds());
|
||||
zkConfig.setSessionTimeoutMilliseconds(zookeeperProperties.getSessionTimeoutMilliseconds());
|
||||
return new ZookeeperRegistryCenter(zkConfig);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.baiye.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/17
|
||||
*/
|
||||
@Configuration
|
||||
public class WebSocketConfig {
|
||||
|
||||
@Bean
|
||||
public ServerEndpointExporter serverEndpointExporter() {
|
||||
return new ServerEndpointExporter();
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.baiye.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "elastic.job.zk")
|
||||
@Data
|
||||
public class ZookeeperProperties {
|
||||
/**
|
||||
* 连接Zookeeper服务器的列表. 包括IP地址和端口号. 多个地址用逗号分隔. 如: host1:2181,host2:2181
|
||||
*/
|
||||
private String serverLists;
|
||||
|
||||
/**
|
||||
* 命名空间.
|
||||
*/
|
||||
private String namespace;
|
||||
|
||||
/**
|
||||
* 等待重试的间隔时间的初始值. 单位毫秒.
|
||||
*/
|
||||
private int baseSleepTimeMilliseconds = 1000;
|
||||
|
||||
/**
|
||||
* 等待重试的间隔时间的最大值. 单位毫秒.
|
||||
*/
|
||||
private int maxSleepTimeMilliseconds = 3000;
|
||||
|
||||
/**
|
||||
* 最大重试次数.
|
||||
*/
|
||||
private int maxRetries = 3;
|
||||
|
||||
/**
|
||||
* 会话超时时间. 单位毫秒.
|
||||
*/
|
||||
private int sessionTimeoutMilliseconds;
|
||||
|
||||
/**
|
||||
* 连接超时时间. 单位毫秒.
|
||||
*/
|
||||
private int connectionTimeoutMilliseconds;
|
||||
|
||||
/**
|
||||
* 连接Zookeeper的权限令牌. 缺省为不需要权限验证.
|
||||
*/
|
||||
private String digest;
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.baiye.dao;
|
||||
|
||||
import com.baiye.entity.CallClueInfo;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/13
|
||||
*/
|
||||
@Repository
|
||||
public interface CallClueRepository extends JpaRepository<CallClueInfo, Long>, JpaSpecificationExecutor<CallClueInfo> {
|
||||
/**
|
||||
* 主键查询
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
CallClueInfo findByClueId(Long id);
|
||||
|
||||
/**
|
||||
* 按条件查询
|
||||
*
|
||||
* @param memberId
|
||||
* @return
|
||||
*/
|
||||
@Query("select d from CallClueInfo d where d.memberId=?1 ")
|
||||
List<CallClueInfo> selectByMember(Long memberId);
|
||||
|
||||
/**
|
||||
* 按条件查询
|
||||
*
|
||||
* @param taskId
|
||||
* @param day
|
||||
* @return
|
||||
*/
|
||||
@Query("select d from CallClueInfo d where d.taskId=?1 and concat(d.createTime,'') =?2 ")
|
||||
List<CallClueInfo> selectByCondition(Long taskId, String day);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.baiye.dao;
|
||||
|
||||
import com.baiye.entity.ReportDay;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/13
|
||||
*/
|
||||
@Repository
|
||||
public interface ReportDayRepository extends JpaRepository<ReportDay, Long>, JpaSpecificationExecutor<ReportDay> {
|
||||
/**
|
||||
* 通过任务id 查询所有的日报
|
||||
*
|
||||
* @param taskId
|
||||
* @return
|
||||
*/
|
||||
List<ReportDay> findAllByTaskId(Long taskId);
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.baiye.entity;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import com.baiye.model.entity.BaseCallClueInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
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 wjt
|
||||
* @date 2021/12/13
|
||||
* 线索中间表
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "tb_call_clue")
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
public class CallClueInfo extends BaseCallClueInfo implements Serializable {
|
||||
private static final long serialVersionUID = -2063303635710762496L;
|
||||
|
||||
@Id
|
||||
@Column(name = "clue_id")
|
||||
private Long clueId;
|
||||
@LastModifiedDate
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.baiye.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/11/30
|
||||
*/
|
||||
@Data
|
||||
public class JobBriefInfo implements Serializable,Comparable<JobBriefInfo> {
|
||||
private static final long serialVersionUID = -2150981397641113926L;
|
||||
|
||||
private String jobName;
|
||||
private JobStatus status;
|
||||
private String description;
|
||||
private String cron;
|
||||
private int instanceCount;
|
||||
private int shardingTotalCount;
|
||||
|
||||
@Override
|
||||
public int compareTo(JobBriefInfo o) {
|
||||
return this.getJobName().compareTo(o.getJobName());
|
||||
}
|
||||
|
||||
public static enum JobStatus {
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
OK,
|
||||
/**
|
||||
* 下线
|
||||
*/
|
||||
CRASHED,
|
||||
/**
|
||||
* 失效
|
||||
*/
|
||||
DISABLED,
|
||||
/**
|
||||
* 分片中
|
||||
*/
|
||||
SHARDING_FLAG;
|
||||
|
||||
private JobStatus() {
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.baiye.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/09
|
||||
*/
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "tb_report_day")
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
public class ReportDay implements Serializable {
|
||||
private static final long serialVersionUID = 4019826389911404260L;
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
private String taskName;
|
||||
private Long memberId;
|
||||
private Long taskId;
|
||||
private Integer turnOnNum;
|
||||
private Double turnOnRate;
|
||||
private Double usrRate;
|
||||
private Integer totalNum;
|
||||
@CreatedDate
|
||||
@Column(name = "create_time")
|
||||
|
||||
private Date createTime;
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.baiye.entity.vo;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/09
|
||||
*/
|
||||
@Data
|
||||
public class MemberInfoVO {
|
||||
/**
|
||||
* 成员id
|
||||
*/
|
||||
private Long memberId;
|
||||
/**
|
||||
* 接通数
|
||||
*/
|
||||
private Integer turnOnNum;
|
||||
/**
|
||||
* 接通率
|
||||
*/
|
||||
private Double turnOnRate;
|
||||
/**
|
||||
* 使用率
|
||||
*/
|
||||
private Double usrRate;
|
||||
/**
|
||||
* 总数
|
||||
*/
|
||||
private Integer totalNum;
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DatePattern.NORM_DATETIME_PATTERN, timezone = "GMT+8")
|
||||
private Date date;
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.baiye.entity.vo;
|
||||
|
||||
import com.baiye.entity.ReportDay;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/13
|
||||
*/
|
||||
@Data
|
||||
public class ReportMessageInfoVO {
|
||||
private Long sessionId;
|
||||
|
||||
private List<ReportDay> list;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.baiye.feign;
|
||||
|
||||
import com.baiye.model.dto.TaskQueryCriteria;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wujingtao
|
||||
* @date 2021/12/27
|
||||
*/
|
||||
@FeignClient(name = "ad-platform-management")
|
||||
public interface ConnectManageFeign {
|
||||
String API_PREFIX = "/api";
|
||||
|
||||
@ApiOperation("查询任务")
|
||||
@PostMapping(API_PREFIX + "/task/query")
|
||||
ResponseEntity<Object> query(@RequestBody TaskQueryCriteria taskQueryCriteria);
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.baiye.feign;
|
||||
|
||||
import com.baiye.model.dto.TaskQueryCriteria;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author wujingtao
|
||||
* @date 2021/12/27
|
||||
*/
|
||||
@Component
|
||||
public class ConnectManageFeignFallBack implements ConnectManageFeign {
|
||||
@Override
|
||||
public ResponseEntity<Object> query(TaskQueryCriteria taskQueryCriteria) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.baiye.feign;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
|
||||
/**
|
||||
* @author wujingtao
|
||||
* @date 2021/12/23
|
||||
*/
|
||||
@FeignClient(name = "ad-platform-source")
|
||||
public interface ConnectSourceFeign {
|
||||
|
||||
|
||||
@ApiOperation("查询组员资源总数")
|
||||
@GetMapping("/source/clue/queryMemberNum")
|
||||
ResponseEntity<Object> queryMemberNum(@RequestParam("memberId") Long memberId);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.baiye.feign;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
/**
|
||||
* @author wujingtao
|
||||
* @date 2021/12/23
|
||||
*/
|
||||
@Component
|
||||
public class ConnectSourceFeignFallBack implements ConnectSourceFeign {
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Object> queryMemberNum(Long memberId) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.baiye.job;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.baiye.entity.jobInstance.ElasticSimpleJob;
|
||||
import com.baiye.service.ReportService;
|
||||
import com.dangdang.ddframe.job.api.ShardingContext;
|
||||
import com.dangdang.ddframe.job.api.simple.SimpleJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.naming.Name;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/10
|
||||
* 每小时调用一次
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@ElasticSimpleJob(jobName = "StatisticsHourJob", cron = "0 0 0/1 * * ?", jobExceptionHandler = "com.baiye.exception.ElasticException", overwrite = true)
|
||||
public class StatisticsHourJob implements SimpleJob {
|
||||
@Resource
|
||||
private ReportService reportService;
|
||||
private static StatisticsHourJob statisticsHourJob;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
statisticsHourJob = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(ShardingContext shardingContext) {
|
||||
log.info("每小时调用一次 {} 点", DateUtil.hour(DateUtil.date(), true));
|
||||
statisticsHourJob.reportService.reportHour();
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.baiye.listener;
|
||||
|
||||
import com.dangdang.ddframe.job.executor.ShardingContexts;
|
||||
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/02
|
||||
*/
|
||||
@Slf4j
|
||||
public class JobListener implements ElasticJobListener {
|
||||
/**
|
||||
* 作业执行前
|
||||
*/
|
||||
@Override
|
||||
public void beforeJobExecuted(ShardingContexts shardingContexts) {
|
||||
log.info("我是 : {} 作业, {}开始执行!", shardingContexts.getJobName(), LocalDateTime.now());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterJobExecuted(ShardingContexts shardingContexts) {
|
||||
log.info("我是 : {} 作业, {}结束执行!", shardingContexts.getJobName(), LocalDateTime.now());
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.baiye.service;
|
||||
|
||||
import com.baiye.entity.Job;
|
||||
import com.baiye.entity.JobBriefInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/11/26
|
||||
*/
|
||||
public interface ElasticJobService {
|
||||
|
||||
/**
|
||||
* 注册job
|
||||
*
|
||||
* @param job
|
||||
*/
|
||||
void addJob(Job job);
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
void removeJob(String jobName);
|
||||
|
||||
/**
|
||||
* 查询job信息
|
||||
*
|
||||
* @param jobName
|
||||
* @return
|
||||
*/
|
||||
Job getJobDetail(String jobName);
|
||||
|
||||
/**
|
||||
* 查询所有的任务基本信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<JobBriefInfo> getAllJobsDetails();
|
||||
|
||||
/**
|
||||
* 修改任务参数
|
||||
*
|
||||
* @param job
|
||||
*/
|
||||
void updateJob(Job job);
|
||||
|
||||
/**
|
||||
* 手动触发
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
void trigger(String jobName);
|
||||
|
||||
/**
|
||||
* 手动失效
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
void disable(String jobName);
|
||||
|
||||
/**
|
||||
* 手动生效
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
void enable(String jobName);
|
||||
|
||||
/**
|
||||
* 终止
|
||||
*
|
||||
* @param jobName
|
||||
*/
|
||||
void shutdown(String jobName);
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.baiye.service;
|
||||
|
||||
import com.baiye.entity.vo.MemberInfoVO;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/10
|
||||
*/
|
||||
public interface ReportService {
|
||||
/**
|
||||
* 推送管理员统计信息
|
||||
*/
|
||||
void reportHour();
|
||||
|
||||
/**
|
||||
* 获取成员接通信息
|
||||
*
|
||||
* @param memberId
|
||||
* @return
|
||||
*/
|
||||
MemberInfoVO getMemberReport(Long memberId);
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
package com.baiye.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baiye.dao.CallClueRepository;
|
||||
import com.baiye.dao.ReportDayRepository;
|
||||
import com.baiye.entity.CallClueInfo;
|
||||
import com.baiye.entity.ReportDay;
|
||||
import com.baiye.entity.vo.MemberInfoVO;
|
||||
import com.baiye.entity.vo.ReportMessageInfoVO;
|
||||
import com.baiye.feign.ConnectManageFeign;
|
||||
import com.baiye.feign.ConnectSourceFeign;
|
||||
import com.baiye.model.dto.TaskQueryCriteria;
|
||||
import com.baiye.model.enums.CallStatusEnum;
|
||||
import com.baiye.service.ReportService;
|
||||
import com.baiye.socket.WebSocketServer;
|
||||
import com.baiye.util.SecurityUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author wjt
|
||||
* @date 2021/12/10
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ReportServiceImpl implements ReportService {
|
||||
@Resource
|
||||
private WebSocketServer webSocketServer;
|
||||
@Resource
|
||||
private CallClueRepository callClueRepository;
|
||||
@Resource
|
||||
private ReportDayRepository reportDayRepository;
|
||||
@Resource
|
||||
private ConnectSourceFeign connectSourceFeign;
|
||||
@Resource
|
||||
private ConnectManageFeign connectManageFeign;
|
||||
|
||||
@Override
|
||||
public void reportHour() {
|
||||
TaskQueryCriteria taskQueryCriteria = new TaskQueryCriteria();
|
||||
taskQueryCriteria.setIsDistribution(1);
|
||||
ResponseEntity<Object> query = connectManageFeign.query(taskQueryCriteria);
|
||||
JSONArray array = JSONUtil.parseArray(query.getBody());
|
||||
|
||||
//获取当天的信息
|
||||
String today = DateUtil.today();
|
||||
for (Object o : array) {
|
||||
JSONObject jsonObject = (JSONObject) o;
|
||||
Long id = jsonObject.getLong("id");
|
||||
int clueTotal = jsonObject.getInt("totalNumber");
|
||||
String taskName = jsonObject.getStr("taskName");
|
||||
List<CallClueInfo> list = callClueRepository.selectByCondition(id, today);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
continue;
|
||||
}
|
||||
JSONObject json = getMessageInfo(list, clueTotal);
|
||||
ReportDay reportDay = new ReportDay();
|
||||
reportDay.setTaskId(id);
|
||||
reportDay.setTaskName(taskName);
|
||||
reportDay.setTotalNum(clueTotal);
|
||||
reportDay.setTurnOnNum(json.getInt("turnOnNum"));
|
||||
reportDay.setTurnOnRate(json.getDouble("turnOnRate"));
|
||||
reportDay.setUsrRate(json.getDouble("usrRate"));
|
||||
reportDay.setCreateTime(DateUtil.date());
|
||||
List<ReportDay> allByTaskId = reportDayRepository.findAllByTaskId(id);
|
||||
allByTaskId.add(reportDay);
|
||||
ReportMessageInfoVO reportMessageInfoVO = new ReportMessageInfoVO();
|
||||
reportMessageInfoVO.setList(allByTaskId);
|
||||
log.info("当前用户 {}", SecurityUtils.getCurrentUserId());
|
||||
reportMessageInfoVO.setSessionId(SecurityUtils.getCurrentUserId());
|
||||
try {
|
||||
if (DateUtil.hour(DateUtil.date(), true) == 13) {
|
||||
//每天23点的统计 保存在数据库
|
||||
reportDayRepository.save(reportDay);
|
||||
}
|
||||
webSocketServer.sendMessage(reportMessageInfoVO);
|
||||
} catch (Exception e) {
|
||||
log.error("发生websocket异常 {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberInfoVO getMemberReport(Long memberId) {
|
||||
//查询此员工的所有线索
|
||||
ResponseEntity<Object> objectResponseEntity = connectSourceFeign.queryMemberNum(memberId);
|
||||
int total = objectResponseEntity.getStatusCodeValue();
|
||||
MemberInfoVO memberInfoVO = new MemberInfoVO();
|
||||
memberInfoVO.setMemberId(memberId);
|
||||
memberInfoVO.setTotalNum(total);
|
||||
memberInfoVO.setDate(DateUtil.date());
|
||||
memberInfoVO.setTurnOnNum(0);
|
||||
memberInfoVO.setTurnOnRate(0.00);
|
||||
memberInfoVO.setUsrRate(0.00);
|
||||
if (total == 0) {
|
||||
return memberInfoVO;
|
||||
}
|
||||
List<CallClueInfo> callClueInfos = callClueRepository.selectByMember(memberId);
|
||||
if (CollUtil.isEmpty(callClueInfos)) {
|
||||
return memberInfoVO;
|
||||
}
|
||||
JSONObject json = getMessageInfo(callClueInfos, total);
|
||||
memberInfoVO.setTurnOnNum(json.getInt("turnOnNum"));
|
||||
memberInfoVO.setTurnOnRate(json.getDouble("turnOnRate"));
|
||||
memberInfoVO.setUsrRate(json.getDouble("usrRate"));
|
||||
return memberInfoVO;
|
||||
}
|
||||
|
||||
private JSONObject getMessageInfo(List<CallClueInfo> callClueInfos, int total) {
|
||||
int usrNum = 0;
|
||||
int turnOnNum = 0;
|
||||
double turnOnRate = 0.00;
|
||||
double usrRate = 0.00;
|
||||
for (CallClueInfo info : callClueInfos) {
|
||||
if (info.getStatus() != 0) {
|
||||
usrNum++;
|
||||
if (info.getStatus() == CallStatusEnum.ANSWER.getValue()) {
|
||||
turnOnNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//使用率 =使用数/总数
|
||||
usrRate = NumberUtil.div(usrNum, total, 2);
|
||||
if (usrNum != 0) {
|
||||
//接通率=接通数/使用数
|
||||
turnOnRate = NumberUtil.div(turnOnNum, usrNum, 2);
|
||||
}
|
||||
JSONObject json = new JSONObject();
|
||||
json.putOpt("turnOnNum", turnOnNum);
|
||||
json.putOpt("turnOnRate", turnOnRate);
|
||||
json.putOpt("usrRate", usrRate);
|
||||
return json;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
{
|
||||
"properties": [
|
||||
{
|
||||
"name": "elastic.job.zk.serverLists",
|
||||
"type": "java.lang.String",
|
||||
"description": "Zoo keeper server list, delimited by ,",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": "localhost:2181"
|
||||
},
|
||||
{
|
||||
"name": "elastic.job.zk.namespace",
|
||||
"type": "java.lang.String",
|
||||
"description": "Namespace for the jobs",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": "elastic-job"
|
||||
},
|
||||
{
|
||||
"name": "elastic.job.zk.baseSleepTimeMilliseconds",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "等待重试的间隔时间的初始值. 单位毫秒",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": 1000
|
||||
},
|
||||
{
|
||||
"name": "elastic.job.zk.maxSleepTimeMilliseconds",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "等待重试的间隔时间的最大值. 单位毫秒",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": 3000
|
||||
},
|
||||
{
|
||||
"name": "elastic.job.zk.maxRetries",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "最大重试次数",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": 3000
|
||||
},
|
||||
{
|
||||
"name": "elastic.job.zk.sessionTimeoutMilliseconds",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "会话超时时间. 单位毫秒",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"name": "elastic.job.zk.connectionTimeoutMilliseconds",
|
||||
"type": "java.lang.Integer",
|
||||
"description": "连接超时时间. 单位毫秒",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": 0
|
||||
},
|
||||
{
|
||||
"name": "elastic.job.zk.digest",
|
||||
"type": "java.lang.String",
|
||||
"description": "连接Zookeeper的权限令牌. 缺省为不需要权限验证",
|
||||
"sourceType": "com.baiye.config.ZookeeperProperties",
|
||||
"defaultValue": null
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
application:
|
||||
name: @artifactId@
|
||||
server:
|
||||
port: 8869
|
||||
|
||||
elastic:
|
||||
job:
|
||||
zk:
|
||||
namespace: elastic-job
|
||||
serverLists: localhost:2181
|
||||
|
||||
logging:
|
||||
config: classpath:logback-spring.xml
|
||||
|
||||
#密码加密传输,前端公钥加密,后端私钥解密
|
||||
rsa:
|
||||
private_key: MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==
|
||||
|
||||
ribbon:
|
||||
ReadTimeout: 3000
|
||||
ConnectTimeout: 3000
|
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
|
||||
<configuration debug="false" scan="false">
|
||||
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
|
||||
<property name="log.path" value="logs/${spring.application.name}"/>
|
||||
<!-- 彩色日志格式 -->
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
|
||||
<!-- 彩色日志依赖的渲染类 -->
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
|
||||
<conversionRule conversionWord="wex"
|
||||
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
|
||||
<conversionRule conversionWord="wEx"
|
||||
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
|
||||
<!-- Console log output -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log file debug output -->
|
||||
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/debug.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log file error output -->
|
||||
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${log.path}/error.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>ERROR</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!--nacos 心跳 INFO 屏蔽-->
|
||||
<logger name="com.alibaba.nacos" level="OFF">
|
||||
<appender-ref ref="error"/>
|
||||
</logger>
|
||||
|
||||
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="debug"/>
|
||||
<appender-ref ref="error"/>
|
||||
</root>
|
||||
</configuration>
|
Loading…
Reference in New Issue