双呼 和统计

master
wujingtao 3 years ago
parent 58732ba7ab
commit 2c94d18261

@ -0,0 +1,102 @@
package com.baiye.model.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.util.Date;
/**
* @author wujingtao
* @date 2022/01/11
*/
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Data
public class BaseDoubleCallInfo {
@Column(name = "request_id")
@ApiModelProperty(value = "请求的唯一id")
private String requestId;
@Column(name = "clue_id")
@ApiModelProperty(value = "线索id")
private String clueId;
@Column(name = "member_id")
@ApiModelProperty(value = "所属人id")
private Long memberId;
@LastModifiedDate
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
@Column(name = "direction")
@ApiModelProperty(value = "通话的呼叫方向")
private Integer direction;
@Column(name = "sp_id")
@ApiModelProperty(value = "客户的云服务账号")
private String spId;
@Column(name = "app_key")
@ApiModelProperty(value = "隐私保护通话应用的 app_key")
private String appKey;
@Column(name = "icid")
@ApiModelProperty(value = "呼叫记录的唯一标识")
private String icid;
@Column(name = "bind_num")
@ApiModelProperty(value = "隐私保护号码")
private String bindNum;
@Column(name = "caller_num")
@ApiModelProperty(value = "主叫号码")
private String callerNum;
@Column(name = "callee_num")
@ApiModelProperty(value = "被叫号码")
private String calleeNum;
@Column(name = "fwd_display_num")
@ApiModelProperty(value = "转接呼叫时的显示号")
private String fwdDisplayNum;
@Column(name = "fwd_dst_num")
@ApiModelProperty(value = "转接呼叫时的转接号码")
private String fwdDstNum;
@Column(name = "fwd_start_time")
@ApiModelProperty(value = "被叫呼叫操作的开始时间")
private String fwdStartTime;
@Column(name = "call_end_time")
@ApiModelProperty(value = "呼叫结束时间")
private String callEndTime;
@Column(name = "call_out_start_time")
@ApiModelProperty(value = "主叫呼叫开始时间")
private String callOutStartTime;
@Column(name = "call_out_answer_time")
@ApiModelProperty(value = "主叫呼叫应答时间")
private String callOutAnswerTime;
@Column(name = "duration")
@ApiModelProperty(value = "通话时长")
private Integer duration;
@Column(name = "record_flag")
@ApiModelProperty(value = "该字段用于录音标识 0未有 1有")
private Integer recordFlag;
@Column(name = "record_file_download_url")
@ApiModelProperty(value = "录音下载地址")
private String recordFileDownloadUrl;
@Column(name = "binding_id")
@ApiModelProperty(value = "绑定 id同绑定请求中的 bindingId")
private String bindingId;
}

@ -25,14 +25,17 @@ public class BaseTimeTask {
private Date executeTime;
@ApiModelProperty(value = "是否重复执行 0-否 1-是")
@Column(name = "is_repeat")
private Integer isRepeat;
private Integer isRepeat = 1;
@ApiModelProperty(value = "执行状态(针对一次性的任务) 0-未执行1-完成")
@Column(name = "status")
private Integer status;
private Integer status = 0;
@ApiModelProperty(value = "执行内容")
@Column(name = "message")
private String message;
@ApiModelProperty(value = "执行人")
@Column(name = "user_id")
private Long userId;
@ApiModelProperty(value = "消息id")
@Column(name = "message_id")
private Long messageId;
}

@ -112,7 +112,28 @@
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
</dependency>
<!-- easyExcel依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- <artifactId>poi</artifactId>-->
<!-- <version>3.8</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- <artifactId>poi-ooxml</artifactId>-->
<!-- <version>4.1.2</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>poi</artifactId>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
</dependencies>
<!-- 配置插件 -->

@ -3,6 +3,7 @@ package com.baiye.feign;
import com.baiye.model.dto.ClueQueryCriteria;
import com.baiye.model.dto.DistributeResponseDTO;
import com.baiye.model.dto.OrganizeQueryCriteria;
import com.baiye.modules.system.service.dto.ClueMiddleTo;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
@ -44,6 +45,14 @@ public interface SourceClueClient {
@ApiOperation("查询组员ID")
@PostMapping(API_PREFIX + "/findMemberIdList")
ResponseEntity<Set<Long>> findMemberIdList(OrganizeQueryCriteria organizeQueryCriteria);
ResponseEntity<Set<Long>> findMemberIdList(@RequestBody ClueMiddleTo clueMiddleTo);
@ApiOperation("查询组员资源总数")
@GetMapping("/source/clue/queryMemberNum")
ResponseEntity<Object> queryMemberNum(@RequestParam("memberId") Long memberId);
@ApiOperation("根据小组id统计小组资源数")
@GetMapping("/source/clue/count")
ResponseEntity<Object> countClueByGroupId(@RequestParam("groupId") Long groupId);
}

@ -2,11 +2,14 @@ package com.baiye.feign;
import com.baiye.model.dto.ClueQueryCriteria;
import com.baiye.model.dto.DistributeResponseDTO;
import com.baiye.model.dto.OrganizeQueryCriteria;
import com.baiye.modules.system.service.dto.ClueMiddleTo;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
public class SourceClueClientFallback implements SourceClueClient {
@ -36,4 +39,19 @@ public class SourceClueClientFallback implements SourceClueClient {
}
@Override
public ResponseEntity<Set<Long>> findMemberIdList(ClueMiddleTo clueMiddleTo) {
return null;
}
@Override
public ResponseEntity<Object> queryMemberNum(Long memberId) {
return null;
}
@Override
public ResponseEntity<Object> countClueByGroupId(Long groupId) {
return null;
}
}

@ -0,0 +1,121 @@
package com.baiye.modules.report.api;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baiye.http.CommonResponse;
import com.baiye.modules.report.entity.dto.StatisticalReportDTO;
import com.baiye.modules.report.entity.dto.UploadTaskDTO;
import com.baiye.modules.report.service.ReportService;
import com.baiye.util.ExportExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author wjt
* @date 2021/12/14
*/
@RestController
@RequestMapping("/api")
@Slf4j
@Api(tags = "获取统计信息")
public class ReportController {
@Resource
private ReportService reportService;
@GetMapping("/report/all")
@ApiOperation("按任务分组的统计信息")
public CommonResponse<Object> getReportByAll() {
return reportService.getReportByAll();
}
@PostMapping("/report/task")
@ApiOperation("按任务的统计信息")
public CommonResponse<Object> getReportByTask(@RequestBody StatisticalReportDTO s) {
return reportService.getReportByTask(s);
}
@GetMapping("/download/task")
@ApiOperation("导出任务统计信息")
public void downloadTaskReport(HttpServletResponse response, String s) {
StatisticalReportDTO statisticalReportDTO = JSONUtil.toBean(s, StatisticalReportDTO.class);
reportService.downloadTaskReport(response, statisticalReportDTO);
}
// @GetMapping("/download/task")
// @ApiOperation("hutool导出测试")
// public void downloadTaskReport(HttpServletResponse response) {
// UploadTask uploadTaskDTO = new UploadTask();
// uploadTaskDTO.setCreateTime("2020");
// uploadTaskDTO.setTaskName("ww");
// uploadTaskDTO.setUsrNum(1);
// UploadTask uploadTaskDTO1 = new UploadTask();
// uploadTaskDTO1.setCreateTime("2022");
// uploadTaskDTO1.setTaskName("wwww");
// uploadTaskDTO1.setUsrNum(2);
// List<UploadTask> list = new ArrayList<>();
// list.add(uploadTaskDTO1);
// list.add(uploadTaskDTO);
//
// try {
// ExcelWriter excelWriter = ExcelUtil.getWriter(true);
// excelWriter.write(list);
// response.reset();
// response.setContentType("application/vnd.ms-excel");
// response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("test.xlsx", "UTF-8"));
// excelWriter.flush(response.getOutputStream());
// excelWriter.close();
// } catch (Exception e) {
// log.error("{}", e.getMessage());
// }
// }
//
// @Data
// class UploadTask {
// private String createTime;
// private String taskName;
// private Integer usrNum;
// }
//
// @PostMapping("/report/organize")
// @ApiOperation("按组的统计信息")
// public CommonResponse<Object> getReportByOrganize(@RequestBody StatisticalReportDTO s) {
// return reportService.getReportByOrganize(s);
// }
@PostMapping("/download/organize")
@ApiOperation("导出组成员统计信息")
public void downloadOrganizeReport(@RequestBody StatisticalReportDTO s) {
HttpServletResponse response = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getResponse();
reportService.downloadOrganizeReport(response, s);
}
@GetMapping("/report/member")
@ApiOperation("获取单个成员统计信息")
public CommonResponse<Object> getMemberReport(String beginTime, String endTime, Long memberId) {
return reportService.getMemberReport(beginTime, endTime, memberId);
}
@GetMapping("/download/member")
@ApiOperation("导出单个成员统计信息")
public void downloadMemberReport(HttpServletResponse response, String beginTime, String endTime, Long memberId) {
reportService.downloadMemberReport(response, beginTime, endTime, memberId);
}
}

@ -0,0 +1,34 @@
package com.baiye.modules.report.dao;
import com.baiye.modules.report.entity.ReportTask;
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 ReportDayRepository extends JpaRepository<ReportTask, Long>, JpaSpecificationExecutor<ReportTask> {
/**
* id
*
* @param taskId
* @return
*/
List<ReportTask> findAllByTaskId(Long taskId);
/**
*
* @param beginTime
* @param endTime
* @param ids
* @return
*/
@Query(value = "select * from tb_report_task d where (d.create_time between ?1 and ?2) and (coalesce (?3,null) is null or d.task_id in (?3))", nativeQuery = true)
List<ReportTask> selectAllByCondition(String beginTime, String endTime, List<Long> ids);
}

@ -0,0 +1,27 @@
package com.baiye.modules.report.dao;
import com.baiye.modules.report.entity.ReportOrganize;
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 wujingtao
* @date 2022/01/11
*/
@Repository
public interface ReportOrganizeRepository extends JpaRepository<ReportOrganize, Long>, JpaSpecificationExecutor<ReportOrganize> {
/**
*
*
* @param beginTime
* @param endTime
* @param ids
* @return
*/
@Query(value = "select * from tb_report_organize d where (d.create_time between ?1 and ?2) and (coalesce (?3,null) is null or d.organize_id in (?3))", nativeQuery = true)
List<ReportOrganize> selectAllByCondition(String beginTime, String endTime, List<Long> ids);
}

@ -0,0 +1,39 @@
package com.baiye.modules.report.entity;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
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 wujingtao
* @date 2022/01/11
*/
@Data
@Entity
@Table(name = "tb_report_organize")
@EntityListeners(AuditingEntityListener.class)
public class ReportOrganize implements Serializable {
private static final long serialVersionUID = 9034474268733855182L;
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String organizeName;
private Long organizeId;
private Integer turnOnNum;
private Double turnOnRate;
private Double usrRate;
private Integer totalNum;
private Integer usrNum;
@CreatedDate
@Column(name = "create_time")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DatePattern.NORM_DATE_PATTERN, timezone = "GMT+8")
private Date createTime;
}

@ -1,5 +1,7 @@
package com.baiye.modules.report.entity;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@ -14,24 +16,24 @@ import java.util.Date;
*/
@Data
@Entity
@Table(name = "tb_report_day")
@Table(name = "tb_report_task")
@EntityListeners(AuditingEntityListener.class)
public class ReportDay implements Serializable {
public class ReportTask 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 usrNum;
private Integer totalNum;
@CreatedDate
@Column(name = "create_time")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DatePattern.NORM_DATE_PATTERN, timezone = "GMT+8")
private Date createTime;
}

@ -0,0 +1,27 @@
package com.baiye.modules.report.entity.dto;
import lombok.Data;
import java.util.List;
/**
* @author wujingtao
* @date 2022/01/10
*/
@Data
public class StatisticalReportDTO {
/**
*
*/
private String beginTime;
/**
*
*/
private String endTime;
/**
* =1=2=3
*/
private Integer type;
private List<Long> ids;
}

@ -0,0 +1,54 @@
package com.baiye.modules.report.entity.dto;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @author wujingtao
* @date 2022/01/14
*/
@Data
public class UploadTaskDTO {
/**
*
*/
@ExcelProperty(value = "日期", index = 0)
private String createTime;
// @ExcelIgnore
private Long taskId;
@ExcelProperty(value = "任务名称", index = 1)
private String taskName;
/**
*
*/
@ExcelProperty(value = "外呼数量", index = 2)
private Integer usrNum;
/**
*
*/
@ExcelProperty(value = "外呼接通量", index = 3)
private Integer turnOnNum;
/**
*
*/
@ExcelProperty(value = "外呼接通率", index = 4)
private Double turnOnRate;
/**
*
*/
@ExcelProperty(value = "外呼总时长", index = 5)
private Integer breatheTotalDuration;
/**
*
*/
@ExcelProperty(value = "平均通话时长", index = 6)
private Double breatheAverageDuration;
@ExcelProperty(value = "标签", index = 7)
private String label;
}

@ -0,0 +1,70 @@
package com.baiye.modules.report.entity.vo;
//import com.alibaba.excel.annotation.ExcelIgnore;
//import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author wjt
* @date 2021/12/09
*/
@Data
@EqualsAndHashCode
public class MemberInfoVO {
/**
* id
*/
@ExcelIgnore
private Long memberId;
/**
*
*/
@ExcelProperty(value = "姓名", index = 2)
private String memberName;
/**
* id
*/
@ExcelIgnore
private Long organizeId;
/**
*
*/
@ExcelProperty(value = "小组", index = 1)
private String organizeName;
/**
*
*/
@ExcelProperty(value = "外呼接通量", index = 4)
private Integer turnOnNum;
/**
*
*/
@ExcelProperty(value = "外呼接通率", index = 5)
private Double turnOnRate;
/**
*
*/
@ExcelProperty(value = "外呼数量", index = 3)
private Integer usrNum;
/**
*
*/
@ExcelProperty(value = "外呼总时长", index = 6)
private Integer breatheTotalDuration;
/**
*
*/
@ExcelProperty(value = "平均通话时长", index = 7)
private Double breatheAverageDuration;
/**
*
*/
@ExcelProperty(value = "日期", index = 0)
private String createTime;
}

@ -0,0 +1,19 @@
package com.baiye.modules.report.entity.vo;
import com.baiye.modules.report.entity.ReportOrganize;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author wujingtao
* @date 2022/01/11
*/
@Data
public class OrganizeInfosVO implements Serializable {
private static final long serialVersionUID = 133887339450743290L;
private Long organizationId;
private String organizationName;
private List<ReportOrganize> data;
}

@ -1,6 +1,6 @@
package com.baiye.modules.report.entity.vo;
import com.baiye.modules.report.entity.ReportDay;
import com.baiye.modules.report.entity.ReportTask;
import lombok.Data;
import java.io.Serializable;
@ -15,5 +15,5 @@ public class TaskInfosVO implements Serializable {
private static final long serialVersionUID = 1546722887341864964L;
private Long taskId;
private String taskName;
private List<ReportDay> data;
private List<ReportTask> data;
}

@ -0,0 +1,74 @@
package com.baiye.modules.report.service;
import com.baiye.http.CommonResponse;
import com.baiye.modules.report.entity.dto.StatisticalReportDTO;
import javax.servlet.http.HttpServletResponse;
/**
* @author wjt
* @date 2021/12/10
*/
public interface ReportService {
/**
*
*
* @return
*/
CommonResponse<Object> getReportByAll();
/**
*
*
* @param s
* @return
*/
CommonResponse<Object> getReportByTask(StatisticalReportDTO s);
/**
*
*
* @param response
* @param s
*/
void downloadTaskReport(HttpServletResponse response, StatisticalReportDTO s);
/**
*
*
* @param s
* @return
*/
CommonResponse<Object> getReportByOrganize(StatisticalReportDTO s);
/**
*
*
* @param response
* @param s
*/
void downloadOrganizeReport(HttpServletResponse response, StatisticalReportDTO s);
/**
*
*
* @param beginTime
* @param endTime
* @param memberId
* @return
*/
CommonResponse<Object> getMemberReport(String beginTime, String endTime, Long memberId);
/**
*
*
* @param response
* @param beginTime
* @param endTime
* @param memberId
* @return
*/
void downloadMemberReport(HttpServletResponse response, String beginTime, String endTime, Long memberId);
}

@ -0,0 +1,531 @@
package com.baiye.modules.report.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
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 com.baiye.constant.DefaultNumberConstants;
import com.baiye.http.CommonResponse;
import com.baiye.model.enums.CallStatusEnum;
import com.baiye.modules.report.entity.dto.StatisticalReportDTO;
import com.baiye.modules.report.entity.dto.UploadTaskDTO;
import com.baiye.modules.report.entity.vo.MemberInfoVO;
import com.baiye.modules.report.service.ReportService;
import com.baiye.modules.system.domain.Organize;
import com.baiye.modules.system.domain.Task;
import com.baiye.modules.system.domain.User;
import com.baiye.modules.system.repository.OrganizeRepository;
import com.baiye.modules.system.repository.TaskRepository;
import com.baiye.modules.system.repository.UserRepository;
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.util.DateTimeUtil;
import com.baiye.util.ExportExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author wjt
* @date 2021/12/10
*/
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
@Resource
private CallClueRepository callClueRepository;
@Resource
private DoubleCallRepository doubleCallRepository;
@Resource
private TaskRepository taskRepository;
@Resource
private OrganizeRepository organizeRepository;
@Resource
private UserRepository userRepository;
@Override
public CommonResponse<Object> getReportByAll() {
List<CallClueInfo> all = callClueRepository.selectByDay(DateTimeUtil.getBeginTimeByDay(DateUtil.today()), DateTimeUtil.getEndTimeByDay(DateUtil.today()));
if (CollUtil.isEmpty(all)) {
return CommonResponse.createByErrorMessage("没有呼叫记录");
}
MemberInfoVO messageInfo = getMessageInfo(DateTimeUtil.getBeginTimeByDay(DateUtil.today()), DateTimeUtil.getEndTimeByDay(DateUtil.today()), all);
return CommonResponse.createBySuccess(messageInfo);
}
@Override
public CommonResponse<Object> getReportByTask(StatisticalReportDTO s) {
StatisticalReportDTO dto = getStatisticalReportDTO(s);
List<CallClueInfo> callClueInfos = getCallClueInfos(dto.getBeginTime(), dto.getEndTime(), dto.getType(), dto.getIds());
if (callClueInfos == null) {
return CommonResponse.createByErrorMessage("请检查时间类型是否错误");
}
//以任务分组
List<HashMap<String, Object>> mapByTask = getMapByTask(dto, getGroupTask(dto.getIds(), callClueInfos));
return CommonResponse.createBySuccess(mapByTask);
}
@Override
public void downloadTaskReport(HttpServletResponse response, StatisticalReportDTO s) {
StatisticalReportDTO dto = getStatisticalReportDTO(s);
List<CallClueInfo> callClueInfos = getCallClueInfos(dto.getBeginTime(), dto.getEndTime(), dto.getType(), dto.getIds());
List<UploadTaskDTO> mapByTaskUpload = getMapByTaskUpload(dto, getGroupTask(dto.getIds(), callClueInfos));
ExportExcelUtil.downloadEasyExcel(response, UploadTaskDTO.class, mapByTaskUpload);
}
@Override
public CommonResponse<Object> getReportByOrganize(StatisticalReportDTO s) {
String beginTime = s.getBeginTime();
String endTime = s.getEndTime();
if (StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime)) {
beginTime = DateTimeUtil.getBeginTimeByDay(DateUtil.today());
endTime = DateTimeUtil.getEndTimeByDay(DateUtil.today());
} else {
beginTime = DateTimeUtil.getBeginTimeByDay(beginTime);
endTime = DateTimeUtil.getEndTimeByDay(endTime);
}
//按时间和组id查询拨打线索记录
List<CallClueInfo> callClueInfos = callClueRepository.selectAllByTimeAndTeamId(beginTime, endTime, s.getIds());
Map<Long, List<CallClueInfo>> map = new HashMap<>(16);
callClueInfos.stream().collect(Collectors.groupingBy(CallClueInfo::getTeamId, Collectors.toList())).forEach(map::put);
List<MemberInfoVO> memberInfoVos = new ArrayList<>();
for (long key : map.keySet()) {
List<CallClueInfo> list = map.get(key);
String organizationName = null;
if (CollUtil.isNotEmpty(list)) {
Long organizeId = list.get(0).getTeamId();
Organize organizeById = organizeRepository.findOrganizeById(organizeId);
if (ObjectUtil.isNotNull(organizeById)) {
organizationName = organizeById.getOrganizeName();
}
}
MemberInfoVO messageInfo = getMessageInfo(beginTime, endTime, list);
messageInfo.setOrganizeName(organizationName);
memberInfoVos.add(messageInfo);
}
return CommonResponse.createBySuccess(memberInfoVos);
}
@Override
public void downloadOrganizeReport(HttpServletResponse response, StatisticalReportDTO s) {
String beginTime = s.getBeginTime();
String endTime = s.getEndTime();
if (StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime)) {
beginTime = DateTimeUtil.getBeginTimeByDay(DateUtil.today());
endTime = DateTimeUtil.getEndTimeByDay(DateUtil.today());
} else {
beginTime = DateTimeUtil.getBeginTimeByDay(beginTime);
endTime = DateTimeUtil.getEndTimeByDay(endTime);
}
//按时间和组id查询拨打线索记录
List<CallClueInfo> callClueInfos = callClueRepository.selectAllByTimeAndTeamId(beginTime, endTime, s.getIds());
//按人分组
Map<Long, List<CallClueInfo>> mapByMember = new HashMap<>(16);
callClueInfos.stream().collect(Collectors.groupingBy(CallClueInfo::getMemberId, Collectors.toList())).forEach(mapByMember::put);
List<MemberInfoVO> memberInfoVos = new ArrayList<>();
for (long key : mapByMember.keySet()) {
//每个人的数据
List<CallClueInfo> list = mapByMember.get(key);
User userById = userRepository.findUserById(key);
String userName = null;
if (ObjectUtil.isNotNull(userById)) {
userName = userById.getUsername();
}
String organizationName = null;
if (CollUtil.isNotEmpty(list)) {
Long organizeId = list.get(0).getTeamId();
Organize organizeById = organizeRepository.findOrganizeById(organizeId);
if (ObjectUtil.isNotNull(organizeById)) {
organizationName = organizeById.getOrganizeName();
}
}
MemberInfoVO messageInfo = getMessageInfo(beginTime, endTime, list);
messageInfo.setOrganizeName(organizationName);
messageInfo.setMemberName(userName);
messageInfo.setCreateTime(beginTime + "至" + endTime);
memberInfoVos.add(messageInfo);
}
HashMap<String, List<MemberInfoVO>> mapByTeam = new HashMap<>(8);
memberInfoVos.stream().collect(Collectors.groupingBy(MemberInfoVO::getOrganizeName, Collectors.toList())).forEach(mapByTeam::put);
ExportExcelUtil.exportPackByDate(response, mapByTeam, "小组统计");
}
@Override
public CommonResponse<Object> getMemberReport(String beginTime, String endTime, Long memberId) {
String begin;
String end;
if (StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime)) {
begin = DateTimeUtil.getBeginTimeByDay(DateUtil.today());
end = DateTimeUtil.getEndTimeByDay(DateUtil.today());
} else {
begin = DateTimeUtil.getBeginTimeByDay(beginTime);
end = DateTimeUtil.getEndTimeByDay(endTime);
}
if (memberId == null) {
log.error("成员id为空");
return CommonResponse.createByErrorMessage("成员id为空");
}
List<CallClueInfo> callClueInfos = callClueRepository.selectAllByTimeAndMemberId(begin, end, memberId);
MemberInfoVO messageInfo = getMessageInfo(begin, end, callClueInfos);
messageInfo.setMemberId(memberId);
return CommonResponse.createBySuccess(messageInfo);
}
@Override
public void downloadMemberReport(HttpServletResponse response, String beginTime, String endTime, Long memberId) {
String begin;
String end;
if (StrUtil.isBlank(beginTime) || StrUtil.isBlank(endTime)) {
begin = DateTimeUtil.getBeginTimeByDay(DateUtil.today());
end = DateTimeUtil.getEndTimeByDay(DateUtil.today());
} else {
begin = DateTimeUtil.getBeginTimeByDay(beginTime);
end = DateTimeUtil.getEndTimeByDay(endTime);
}
if (memberId == null) {
log.error("成员id为空");
return;
}
List<CallClueInfo> callClueInfos = callClueRepository.selectAllByTimeAndMemberId(begin, end, memberId);
if (CollUtil.isEmpty(callClueInfos)) {
return;
}
User userById = userRepository.findUserById(memberId);
String userName = null;
if (ObjectUtil.isNotNull(userById)) {
userName = userById.getUsername();
}
String organizationName = null;
Long organizeId = callClueInfos.get(0).getTeamId();
Organize organizeById = organizeRepository.findOrganizeById(organizeId);
if (ObjectUtil.isNotNull(organizeById)) {
organizationName = organizeById.getOrganizeName();
}
//按时间分组
HashMap<String, List<CallClueInfo>> clues = getGroupByTime(begin, end, callClueInfos, 2);
List<MemberInfoVO> list = new ArrayList<>();
for (String key : clues.keySet()) {
List<CallClueInfo> clueInfos = clues.get(key);
if (CollUtil.isEmpty(clueInfos)) {
continue;
}
MemberInfoVO messageInfo = getMessageInfo(begin, end, clueInfos);
messageInfo.setMemberName(userName);
messageInfo.setOrganizeName(organizationName);
messageInfo.setCreateTime(key);
list.add(messageInfo);
}
ExportExcelUtil.downloadEasyExcel(response, MemberInfoVO.class, list);
}
/**
*
*
* @param s
* @return
*/
private StatisticalReportDTO getStatisticalReportDTO(StatisticalReportDTO s) {
List<Long> ids = s.getIds();
if (CollUtil.isEmpty(ids)) {
ids = new ArrayList<>();
getTaskId(ids);
s.setIds(ids);
}
String beginTime = s.getBeginTime();
String endTime = s.getEndTime();
Integer type = s.getType();
if (StrUtil.isBlank(beginTime) && StrUtil.isBlank(endTime)) {
endTime = DateUtil.today();
beginTime = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -7), "yyyy-MM-dd");
type = 2;
s.setBeginTime(beginTime);
s.setEndTime(endTime);
s.setType(type);
}
return s;
}
/**
*
*
* @param beginTime
* @param endTime
* @param type
* @param ids
* @return
*/
private List<CallClueInfo> getCallClueInfos(String beginTime, String endTime, Integer type, List<Long> ids) {
List<CallClueInfo> callClueInfos = new ArrayList<>();
String begin;
String end;
switch (type) {
case 2:
begin = DateTimeUtil.getBeginTimeByDay(beginTime);
end = DateTimeUtil.getEndTimeByDay(endTime);
callClueInfos = callClueRepository.selectAllByTimeAndTaskId(begin, end, ids);
break;
case 3:
int monthEnd = DateUtil.parse(endTime).month();
int monthBegin = DateUtil.parse(beginTime).month();
if (monthEnd - monthBegin > 1) {
log.error("---------接受参数类型为月。时间范围超出2个月 ");
return null;
}
begin = DateTimeUtil.getBeginTimeByMonth(beginTime);
end = DateTimeUtil.getEndTimeByMonth(endTime);
callClueInfos = callClueRepository.selectAllByTimeAndTaskId(begin, end, ids);
break;
case 1:
int betweenHour = (int) DateUtil.between(DateUtil.parse(beginTime), DateUtil.parse(endTime), DateUnit.HOUR);
if (betweenHour > 48) {
log.error("---------接受参数类型为小时。时间范围超出48小时 ");
return null;
}
begin = DateTimeUtil.getBeginTimeByHour(beginTime);
end = DateTimeUtil.getEndTimeByHour(endTime);
callClueInfos = callClueRepository.selectAllByTimeAndTaskId(begin, end, ids);
break;
default:
break;
}
return callClueInfos;
}
/**
* idkey
*
* @param ids
* @param callClueInfos
* @return
*/
private HashMap<Long, List<CallClueInfo>> getGroupTask(List<Long> ids, List<CallClueInfo> callClueInfos) {
HashMap<Long, List<CallClueInfo>> map = new HashMap<>();
for (long id : ids) {
List<CallClueInfo> collect = callClueInfos.stream().filter(c -> c.getTaskId() != null && c.getTaskId() == id).collect(Collectors.toList());
if (CollUtil.isEmpty(collect)) {
map.put(id, new ArrayList<>());
} else {
map.put(id, collect);
}
}
return map;
}
/**
* key
*
* @param beginTime
* @param endTime
* @param callClueInfos
* @param type
* @return
*/
private HashMap<String, List<CallClueInfo>> getGroupByTime(String beginTime, String endTime, List<CallClueInfo> callClueInfos, Integer type) {
Date begin = DateUtil.parse(beginTime);
Date end = DateUtil.parse(endTime);
HashMap<String, List<CallClueInfo>> map = new HashMap<>();
switch (type) {
case 2:
int betweenDay = (int) DateUtil.between(begin, end, DateUnit.DAY);
for (int i = 1; i <= betweenDay; i++) {
Date dateTime = DateUtil.offsetDay(begin, i);
List<CallClueInfo> collect = callClueInfos.stream().filter(c -> DateTimeUtil.betweenByDay(dateTime, c.getCreateTime())).collect(Collectors.toList());
map.put(DateTimeUtil.getTimeType(dateTime, type), collect);
}
break;
case 3:
List<CallClueInfo> collect = callClueInfos.stream().filter(c -> DateTimeUtil.betweenByMonth(c.getCreateTime(), begin)).collect(Collectors.toList());
List<CallClueInfo> collect1 = callClueInfos.stream().filter(c -> DateTimeUtil.betweenByMonth(c.getCreateTime(), end)).collect(Collectors.toList());
map.put(DateTimeUtil.getTimeType(begin, type), collect);
map.put(DateTimeUtil.getTimeType(end, type), collect1);
break;
case 1:
int betweenHour = (int) DateUtil.between(begin, end, DateUnit.HOUR);
for (int i = 1; i <= betweenHour; i++) {
Date dateTime = DateUtil.offsetHour(begin, i);
List<CallClueInfo> collectByHour = callClueInfos.stream().filter(c ->
DateTimeUtil.betweenByHour(dateTime, c.getCreateTime())
).collect(Collectors.toList());
map.put(DateTimeUtil.getTimeType(dateTime, type), collectByHour);
}
break;
default:
return map;
}
return map;
}
/**
* 5taskid
*
* @param ids
*/
private void getTaskId(List<Long> ids) {
List<Task> allByIsAndIsDistribution = taskRepository.findAllByIsAndIsDistributionAndId(DefaultNumberConstants.ONE_NUMBER, ids);
if (CollUtil.isNotEmpty(allByIsAndIsDistribution)) {
int flag = 0;
for (int i = allByIsAndIsDistribution.size() - 1; i >= 0; i--) {
if (flag == 5) {
break;
}
flag += 1;
ids.add(allByIsAndIsDistribution.get(i).getId());
}
}
}
/**
* task 使
*
* @param s
* @param mapByTask
* @return
*/
private List<HashMap<String, Object>> getMapByTask(StatisticalReportDTO s, Map<Long, List<CallClueInfo>> mapByTask) {
List<HashMap<String, Object>> listMap = new ArrayList<>();
List<Task> tasks = taskRepository.findAllByIsAndIsDistributionAndId(DefaultNumberConstants.ONE_NUMBER, s.getIds());
//按id分组
Map<Long, Task> taskInfos = new HashMap<>(8);
for (Task info : tasks) {
taskInfos.put(info.getId(), info);
}
for (Long key : mapByTask.keySet()) {
HashMap<String, Object> mapVo = new HashMap<String, Object>();
//按时间分
HashMap<String, List<CallClueInfo>> mapByTime = getGroupByTime(s.getBeginTime(), s.getEndTime(), mapByTask.get(key), s.getType());
int total = taskInfos.get(key).getTotalNumber();
String taskName = taskInfos.get(key).getTaskName();
double usrRate = 0;
ArrayList list = new ArrayList();
for (String keyId : mapByTime.keySet()) {
Map<String, Object> mapByUsrRate = new HashMap<>();
//使用数
long count = mapByTime.get(keyId).stream().filter(c -> c.getStatus() != 0).count();
if (total != 0) {
//使用率
usrRate = NumberUtil.div(count, total, 2);
}
mapByUsrRate.put("usrRate", usrRate);
mapByUsrRate.put("createTime", keyId);
list.add(mapByUsrRate);
}
list.sort(new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
String time1 = (String) o1.get("createTime");
String time2 = (String) o2.get("createTime");
return time1.compareTo(time2);
}
});
mapVo.put("taskName", taskName);
mapVo.put("data", list);
listMap.add(mapVo);
}
return listMap;
}
/**
* task
*
* @param s
* @param mapByTask
* @return
*/
private List<UploadTaskDTO> getMapByTaskUpload(StatisticalReportDTO s, Map<Long, List<CallClueInfo>> mapByTask) {
List<UploadTaskDTO> list = new ArrayList<>();
List<Task> tasks = taskRepository.findAllByIsAndIsDistributionAndId(DefaultNumberConstants.ONE_NUMBER, s.getIds());
//按id分组
Map<Long, Task> taskInfos = new HashMap<>(8);
for (Task info : tasks) {
taskInfos.put(info.getId(), info);
}
for (Long key : mapByTask.keySet()) {
Task task = taskInfos.get(key);
String taskName = task.getTaskName();
List<String> baseLabel = task.getBaseLabel();
StringBuilder label = new StringBuilder();
if (baseLabel.size() > 0) {
for (int i = 0; i < baseLabel.size(); i++) {
if (i == baseLabel.size() - 1) {
label.append(baseLabel.get(i));
} else {
label.append(baseLabel.get(i)).append(",");
}
}
}
List<CallClueInfo> clueInfos = mapByTask.get(key);
if (CollUtil.isEmpty(clueInfos)) {
continue;
}
MemberInfoVO messageInfo = getMessageInfo(s.getBeginTime(), s.getEndTime(), clueInfos);
UploadTaskDTO upload = new UploadTaskDTO();
BeanUtil.copyProperties(messageInfo, upload);
upload.setTaskName(taskName);
upload.setLabel(label.toString());
upload.setCreateTime(s.getBeginTime() + "至" + s.getEndTime());
list.add(upload);
}
return list;
}
/**
*
*
* @param callClueInfos
* @return
*/
private MemberInfoVO getMessageInfo(String begin, String end, List<CallClueInfo> callClueInfos) {
int usrNum = 0;
int turnOnNum = 0;
double turnOnRate = 0.00;
int breatheTotalDuration = 0;
double breatheAverageDuration = 0;
if (CollUtil.isNotEmpty(callClueInfos)) {
for (CallClueInfo info : callClueInfos) {
if (info.getStatus() != 0) {
usrNum++;
if (info.getStatus() == CallStatusEnum.ANSWER.getValue()) {
turnOnNum++;
}
}
long clueId = info.getClueId();
List<DoubleCallInfo> doubleCallInfo = doubleCallRepository.selectAllByTimeAndClueId(begin, end, clueId);
int doubleClueTime = doubleCallInfo.stream().mapToInt(DoubleCallInfo::getDuration).sum();
breatheTotalDuration += doubleClueTime;
}
breatheAverageDuration = NumberUtil.div(breatheTotalDuration, callClueInfos.size(), 2);
}
if (usrNum != 0) {
//接通率=接通数/使用数
turnOnRate = NumberUtil.div(turnOnNum, usrNum, 2);
}
MemberInfoVO memberInfoVO = new MemberInfoVO();
memberInfoVO.setTurnOnNum(turnOnNum);
memberInfoVO.setTurnOnRate(turnOnRate);
memberInfoVO.setUsrNum(usrNum);
memberInfoVO.setBreatheAverageDuration(breatheAverageDuration);
memberInfoVO.setBreatheTotalDuration(breatheTotalDuration);
return memberInfoVO;
}
}

@ -130,6 +130,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers( "/api/users/admin").permitAll()
.antMatchers( "/api/task/query").permitAll()
.antMatchers( "/api/organize/queryAll").permitAll()
.antMatchers( "/api/report/organize").permitAll()
.antMatchers( "/api/download/task").permitAll()
// 自定义匿名访问所有url放行允许匿名和带Token访问细腻化到每个 Request 类型
// GET
.antMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll()

@ -20,4 +20,7 @@ public interface OrganizeRepository extends JpaRepository<Organize, Long>, JpaSp
*/
@Query(value = "select * from tb_organize where organize_id = (select organize_id from tb_organize_user where user_id = ?1)", nativeQuery = true)
Organize findOrganize(Long currentUserId);
@Query(value = "select t from Organize t where t.id =?1")
Organize findOrganizeById(Long id);
}

@ -10,13 +10,23 @@ import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author YQY
* @date 2021-12-10
*/
* @author YQY
* @date 2021-12-10
*/
@Repository
public interface TaskRepository extends JpaRepository<Task, Long>, JpaSpecificationExecutor<Task> {
@Modifying
@Query(value = "update tb_task set is_distribution = ?1 where id = ?2",nativeQuery = true)
void updateIsDistribution(int isDistribution,Long taskId);
@Query(value = "update tb_task set is_distribution = ?1 where id = ?2", nativeQuery = true)
void updateIsDistribution(int isDistribution, Long taskId);
/**
*
*
* @param isDistribution
* @param ids
* @return
*/
@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);
}

@ -39,6 +39,15 @@ public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificat
*/
User findByUsername(String username);
/**
* id
*
* @param id
* @return
*/
@Query(value = "select u from User u where u.id = ?1")
User findUserById(Long id);
/**
*
*
@ -154,6 +163,7 @@ public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificat
/**
* id
*
* @param aTrue
* @return
*/
@ -162,6 +172,7 @@ public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificat
/**
* id
*
* @param managerId managerId
* @return
*/

@ -141,4 +141,9 @@ public class OrganizeController {
return new ResponseEntity<>(organizeService.getLabel(taskId, organizeId), HttpStatus.OK);
}
@ApiOperation("查询所有的组和组线索数量")
@GetMapping("/selectAll")
public ResponseEntity<Object> selectAllOrganize() {
return new ResponseEntity<>(organizeService.selectAllOrganize(), HttpStatus.OK);
}
}

@ -136,4 +136,10 @@ public interface OrganizeService {
* @return
*/
Map<String, List<String>> getLabel(Long taskId, Long organizeId);
/**
*
* @return
*/
List<Organize> selectAllOrganize();
}

@ -0,0 +1,15 @@
package com.baiye.modules.system.service.dto;
import lombok.Data;
/**
* @author wujingtao
* @date 2022/01/18
*/
@Data
public class ClueMiddleTo {
private Long organizeId;
private Long taskId;
}

@ -315,9 +315,12 @@ public class OrganizeServiceImpl implements OrganizeService {
@Override
public TaskOrganize queryDetails(OrganizeQueryCriteria organizeQueryCriteria) {
TaskOrganize updateTaskOrganize = taskOrganizeRepository.findByOrganizeIdAndTaskId(organizeQueryCriteria.getOrganizeId(), organizeQueryCriteria.getTaskId());
Set<Long> memberIdList = sourceClueClient.findMemberIdList(organizeQueryCriteria).getBody();
ClueMiddleTo clueMiddleTo = new ClueMiddleTo();
clueMiddleTo.setOrganizeId(organizeQueryCriteria.getOrganizeId());
clueMiddleTo.setTaskId(organizeQueryCriteria.getTaskId());
Set<Long> memberIdList = sourceClueClient.findMemberIdList(clueMiddleTo).getBody();
List<Long> memberIds = new ArrayList<>(memberIdList);
List<Map<String, Object>> list = findUser(memberIds, null);
List<Map<String, Object>> list = findUser(memberIds, new OrganizeUserQueryCriteria());
updateTaskOrganize.setUserList(list);
return updateTaskOrganize;
}
@ -471,6 +474,11 @@ public class OrganizeServiceImpl implements OrganizeService {
return map;
}
@Override
public List<Organize> selectAllOrganize() {
return organizeRepository.findAll();
}
/**
* id
*/

@ -11,6 +11,7 @@ import com.baiye.modules.telemarkting.service.DoubleCallService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -30,7 +31,7 @@ public class DoubleCallController {
@PostMapping("/double/req")
@ApiOperation("请求接入双呼")
public CommonResponse<Object> doubleCallReq(@RequestBody DoubleCallReqDTO doubleCallReq) {
public CommonResponse<Object> doubleCallReq(@Validated @RequestBody DoubleCallReqDTO doubleCallReq) {
if (ObjectUtil.isEmpty(doubleCallReq)) {
return CommonResponse.createByError();
}

@ -30,4 +30,48 @@ public interface CallClueRepository extends JpaRepository<CallClueInfo, Long>, J
*/
@Query("select d from CallClueInfo d where d.memberId=?1 ")
List<CallClueInfo> selectByMember(Long memberId);
/**
* 线
*
* @param beginTime
* @param endTime
* @return
*/
@Query(value = "select * from tb_call_clue d where (d.create_time between ?1 and ?2)", nativeQuery = true)
List<CallClueInfo> selectByDay(String beginTime, String endTime);
/**
*
*
* @param beginTime
* @param endTime
* @param id
* @return
*/
@Query(value = "select * from tb_call_clue d where (d.create_time between ?1 and ?2) and d.member_id = ?3", nativeQuery = true)
List<CallClueInfo> selectAllByTimeAndMemberId(String beginTime, String endTime, Long id);
/**
* id
*
* @param beginTime
* @param endTime
* @param id
* @return
*/
@Query(value = "select * from tb_call_clue d where (d.create_time between ?1 and ?2) and (coalesce (?3,null) is null or d.team_id in (?3))", nativeQuery = true)
List<CallClueInfo> selectAllByTimeAndTeamId(String beginTime, String endTime, List<Long> id);
/**
* id
*
* @param beginTime
* @param endTime
* @param id
* @return
*/
@Query(value = "select * from tb_call_clue d where (d.create_time between ?1 and ?2) and (coalesce (?3,null) is null or d.task_id in (?3))", nativeQuery = true)
List<CallClueInfo> selectAllByTimeAndTaskId(String beginTime, String endTime, List<Long> id);
}

@ -30,4 +30,15 @@ public interface DoubleCallRepository extends JpaRepository<DoubleCallInfo, Long
*/
@Query("select d from DoubleCallInfo d where d.memberId=?1 ")
List<DoubleCallInfo> selectByMemberAndStatus(Long memberId);
/**
*
*
* @param beginTime
* @param endTime
* @param id
* @return
*/
@Query(value = "select * from tb_double_call d where (d.create_time between ?1 and ?2) and d.clue_id = ?3", nativeQuery = true)
List<DoubleCallInfo> selectAllByTimeAndClueId(String beginTime, String endTime, Long id);
}

@ -3,6 +3,7 @@ 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 io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@ -26,8 +27,12 @@ public class CallClueInfo extends BaseCallClueInfo implements Serializable {
@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;
@Transient
@ApiModelProperty(value = "通话总时长")
private Integer breatheTotalDuration;
}

@ -1,5 +1,6 @@
package com.baiye.modules.telemarkting.entity;
import com.baiye.model.entity.BaseDoubleCallInfo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.annotation.LastModifiedDate;
@ -17,91 +18,11 @@ import java.util.Date;
@Entity
@Table(name = "tb_double_call")
@EntityListeners(AuditingEntityListener.class)
public class DoubleCallInfo implements Serializable {
public class DoubleCallInfo extends BaseDoubleCallInfo implements Serializable {
private static final long serialVersionUID = -1452118686043669994L;
@Id
@Column(name = "id")
@ApiModelProperty(value = "id双呼请求/回调的sessionId")
private String id;
@Column(name = "request_id")
@ApiModelProperty(value = "请求的唯一id")
private String requestId;
@Column(name = "clue_id")
@ApiModelProperty(value = "线索id")
private String clueId;
@Column(name = "member_id")
@ApiModelProperty(value = "所属人id")
private Long memberId;
@LastModifiedDate
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
@Column(name = "direction")
@ApiModelProperty(value = "通话的呼叫方向")
private Integer direction;
@Column(name = "sp_id")
@ApiModelProperty(value = "客户的云服务账号")
private String spId;
@Column(name = "app_key")
@ApiModelProperty(value = "隐私保护通话应用的 app_key")
private String appKey;
@Column(name = "icid")
@ApiModelProperty(value = "呼叫记录的唯一标识")
private String icid;
@Column(name = "bind_num")
@ApiModelProperty(value = "隐私保护号码")
private String bindNum;
@Column(name = "caller_num")
@ApiModelProperty(value = "主叫号码")
private String callerNum;
@Column(name = "callee_num")
@ApiModelProperty(value = "被叫号码")
private String calleeNum;
@Column(name = "fwd_display_num")
@ApiModelProperty(value = "转接呼叫时的显示号")
private String fwdDisplayNum;
@Column(name = "fwd_dst_num")
@ApiModelProperty(value = "转接呼叫时的转接号码")
private String fwdDstNum;
@Column(name = "fwd_start_time")
@ApiModelProperty(value = "被叫呼叫操作的开始时间")
private String fwdStartTime;
@Column(name = "call_end_time")
@ApiModelProperty(value = "呼叫结束时间")
private String callEndTime;
@Column(name = "call_out_start_time")
@ApiModelProperty(value = "主叫呼叫开始时间")
private String callOutStartTime;
@Column(name = "call_out_answer_time")
@ApiModelProperty(value = "主叫呼叫应答时间")
private String callOutAnswerTime;
@Column(name = "duration")
@ApiModelProperty(value = "通话时长")
private Integer duration;
@Column(name = "record_flag")
@ApiModelProperty(value = "该字段用于录音标识 0未有 1有")
private Integer recordFlag;
@Column(name = "record_file_download_url")
@ApiModelProperty(value = "录音下载地址")
private String recordFileDownloadUrl;
@Column(name = "binding_id")
@ApiModelProperty(value = "绑定 id同绑定请求中的 bindingId")
private String bindingId;
}

@ -1,8 +1,11 @@
package com.baiye.modules.telemarkting.entity.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NonNull;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
@ -14,20 +17,30 @@ import java.io.Serializable;
public class DoubleCallReqDTO implements Serializable {
private static final long serialVersionUID = 8037829549747968861L;
/**
*
*/
@ApiModelProperty("真实主叫号码")
@NotNull
private String telA;
/**
*
*/
@ApiModelProperty("真实被叫号码")
@NotNull
private String telB;
private String requestId;
/**
* 线id
*/
@ApiModelProperty("具体线索id")
@NotNull
private String userData;
@ApiModelProperty("小组id")
@NotNull
private Long teamId;
@ApiModelProperty("成员id")
@NotNull
private Long memberId;
@ApiModelProperty("主任务id")
@NotNull
private Long taskId;
}

@ -0,0 +1,114 @@
package com.baiye.util;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import java.util.Date;
/**
* @author wujingtao
* @date 2022/01/13
*/
public class DateTimeUtil {
/**
*
*
* @param beginTime
* @return
*/
public static String getBeginTimeByDay(String beginTime) {
return DateUtil.format(DateUtil.beginOfDay(DateUtil.parse(beginTime)), "yyyy-MM-dd HH:mm:dd");
}
public static String getEndTimeByDay(String endTime) {
return DateUtil.format(DateUtil.endOfDay(DateUtil.parse(endTime)), "yyyy-MM-dd HH:mm:dd");
}
public static String getBeginTimeByMonth(String beginTime) {
return DateUtil.format(DateUtil.beginOfMonth(DateUtil.parse(beginTime)), "yyyy-MM-dd HH:mm:dd");
}
public static String getEndTimeByMonth(String endTime) {
return DateUtil.format(DateUtil.endOfMonth(DateUtil.parse(endTime)), "yyyy-MM-dd HH:mm:dd");
}
public static String getBeginTimeByHour(String beginTime) {
return DateUtil.format(DateUtil.beginOfHour(DateUtil.parse(beginTime)), "yyyy-MM-dd HH:mm:dd");
}
public static String getEndTimeByHour(String endTime) {
return DateUtil.format(DateUtil.endOfHour(DateUtil.parse(endTime)), "yyyy-MM-dd HH:mm:dd");
}
public static String getTimeType(Date dateTime, Integer timeType) {
if (timeType == 2) {
return DateUtil.format(dateTime, "yyyy-MM-dd");
} else if (timeType == 3) {
return DateUtil.format(dateTime, "yyyy-MM");
} else {
return DateUtil.format(dateTime, "yyyy-MM-dd HH");
}
}
/**
*
*
* @return
*/
public static Boolean betweenByDay(Date begin, Date end) {
begin = DateUtil.parse(DateUtil.format(begin, "yyyy-MM-dd"));
end = DateUtil.parse(DateUtil.format(end, "yyyy-MM-dd"));
long between = DateUtil.between(begin, end, DateUnit.DAY);
if (between == 0) {
return true;
}
return false;
}
/**
*
*
* @param begin
* @param end
* @return
*/
public static Boolean betweenByMonth(Date begin, Date end) {
int beginYear = DateUtil.year(begin);
int endYear = DateUtil.year(end);
int beginMonth = DateUtil.month(begin);
int endMonth = DateUtil.month(end);
if (beginYear == endYear) {
if (beginMonth == endMonth) {
return true;
}
}
return false;
}
/**
*
*
* @return
*/
public static Boolean betweenByHour(Date begin, Date end) {
if (betweenByDay(begin, end)) {
int hour1 = DateUtil.hour(begin, true);
int hour2 = DateUtil.hour(end, true);
if (hour1 == hour2) {
return true;
}
}
return false;
}
public static void main(String[] args) {
Date begin = DateUtil.beginOfDay(DateUtil.parse("2022-01-06 12:04:59"));
Date end = DateUtil.endOfDay(DateUtil.parse("2022-1-5"));
long between = DateUtil.between(begin, end, DateUnit.DAY);
System.out.println(between);
}
}

@ -0,0 +1,85 @@
package com.baiye.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
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.List;
import java.util.Map;
@Slf4j
public class ExportExcelUtil {
/**
* excel
*/
@SneakyThrows
public static void downloadEasyExcel(HttpServletResponse response, Object obj, List list) {
String fileName = URLEncoder.encode("表单", "UTF-8");
response.reset();
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
// excel头策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontHeightInPoints((short) 11);
headWriteFont.setBold(false);
headWriteCellStyle.setWriteFont(headWriteFont);
// excel内容策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
WriteFont contentWriteFont = new WriteFont();
//内容水平对齐
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.RIGHT);
contentWriteFont.setFontHeightInPoints((short) 11);
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 设置handler
HorizontalCellStyleStrategy styleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
//写出
EasyExcel.write(response.getOutputStream(), (Class) obj)
.autoCloseStream(Boolean.FALSE)
.sheet("sheet1")
.registerWriteHandler(styleStrategy)
//自动设置列的宽tm
// .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.doWrite(list);
}
public static void exportPackByDate(HttpServletResponse response, Map<String, List<MemberInfoVO>> params, String fileName) {
ExcelWriter excelWriter = null;
try {
// 防止中文乱码
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
//工作簿对象
excelWriter = EasyExcel.write(response.getOutputStream()).build();
int i = 0;
for (String key : params.keySet()) {
//sheet对象
WriteSheet sheet = EasyExcel.writerSheet(i, key).head(MemberInfoVO.class).build();
//写出
excelWriter.write(params.get(key), sheet);
i += 1;
}
} catch (Exception e) {
log.error(e.getMessage());
} finally {
if (excelWriter != null) {
excelWriter.finish();
}
}
}
}

@ -30,17 +30,17 @@
<artifactId>ad-platform-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.dangdang</groupId>-->
<!-- <artifactId>elastic-job-lite-core</artifactId>-->
<!-- <version>2.1.5</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>guava</artifactId>-->
<!-- <groupId>com.google.guava</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.dangdang</groupId>-->
<!-- <artifactId>elastic-job-lite-core</artifactId>-->
<!-- <version>2.1.5</version>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <artifactId>guava</artifactId>-->
<!-- <groupId>com.google.guava</groupId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>

@ -1,6 +1,6 @@
package com.baiye.config;
import com.baiye.modules.elsaticjob.entity.jobInstance.ElasticSimpleJob;
import com.baiye.modules.timetask.entity.jobInstance.ElasticSimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.JobTypeConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;

@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @author wujingtao
* @date 2021/12/27

@ -12,6 +12,8 @@ import java.util.List;
*/
@Component
public class ConnectManageFeignFallBack implements ConnectManageFeign {
@Override
public ResponseEntity<Object> query(TaskQueryCriteria taskQueryCriteria) {
return null;

@ -1,21 +0,0 @@
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);
}

@ -1,18 +0,0 @@
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;
}
}

@ -1,7 +1,7 @@
package com.baiye.job;
import com.baiye.modules.elsaticjob.entity.jobInstance.ElasticSimpleJob;
import com.baiye.modules.elsaticjob.service.impl.AutoReminderServiceImpl;
import com.baiye.modules.timetask.entity.jobInstance.ElasticSimpleJob;
import com.baiye.modules.timetask.service.impl.AutoReminderServiceImpl;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.extern.slf4j.Slf4j;
@ -13,6 +13,7 @@ import javax.annotation.Resource;
/**
* @author wujingtao
* @date 2022/01/05
*
*/
@Slf4j
@Component

@ -1,35 +0,0 @@
package com.baiye.job;
import com.baiye.modules.elsaticjob.entity.jobInstance.ElasticSimpleJob;
import com.baiye.modules.report.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;
/**
* @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) {
statisticsHourJob.reportService.reportHour();
}
}

@ -3,7 +3,7 @@ package com.baiye.job;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.modules.elsaticjob.entity.jobInstance.ElasticSimpleJob;
import com.baiye.modules.timetask.entity.jobInstance.ElasticSimpleJob;
import com.baiye.socket.WebSocketServer;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
@ -16,6 +16,7 @@ import javax.annotation.Resource;
/**
* @author wujingtao
* @date 2021/12/28
* websocket
*/
@Slf4j
@Component

@ -1,68 +0,0 @@
package com.baiye.modules.elsaticjob.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.http.CommonResponse;
import com.baiye.modules.elsaticjob.dao.AutoReminderRepository;
import com.baiye.modules.elsaticjob.entity.AutoReminder;
import com.baiye.modules.elsaticjob.service.AutoReminderService;
import com.baiye.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* @author wujingtao
* @date 2022/01/05
*/
@Slf4j
@Service
public class AutoReminderServiceImpl implements AutoReminderService {
@Resource
private AutoReminderRepository timeTaskRepository;
@Resource
private WebSocketServer webSocketServer;
@Override
public CommonResponse<Object> addTimeTask(AutoReminder timeTask) {
if (timeTaskRepository.save(timeTask).getId() == null) {
return CommonResponse.createByErrorMessage("保存定时任务失败");
}
return CommonResponse.createBySuccess();
}
/**
*
*/
@Transactional(rollbackFor = Exception.class)
public void runAutomaticReminder() {
List<AutoReminder> allByStatus = timeTaskRepository.findAllByStatus(DefaultNumberConstants.ZERO_NUMBER);
if (CollUtil.isEmpty(allByStatus)) {
return;
}
JSONObject object = new JSONObject();
object.putOpt("type", "");
object.putOpt("code", DefaultNumberConstants.TWO_HUNDRED);
for (AutoReminder info : allByStatus) {
if (DateUtil.between(info.getExecuteTime(), DateUtil.date(), DateUnit.HOUR) == 0) {
object.putOpt("message", info.getUserId());
try {
webSocketServer.sendMessage(JSONUtil.toJsonStr(object), String.valueOf(info.getUserId()));
} catch (Exception e) {
log.info("执行自提醒任务 id:{} 发送websocket失败 {}", info.getId(), e.getMessage());
continue;
}
if (info.getIsRepeat() == DefaultNumberConstants.ZERO_NUMBER) {
timeTaskRepository.updateTimeTaskStatus(DefaultNumberConstants.ONE_NUMBER, info.getId());
}
}
}
}
}

@ -1,41 +0,0 @@
package com.baiye.modules.report.api;
import com.baiye.http.CommonResponse;
import com.baiye.modules.report.entity.vo.MemberInfoVO;
import com.baiye.modules.report.service.ReportService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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
@Api(tags = "获取统计信息")
public class ReportController {
@Resource
private ReportService reportService;
@GetMapping("/report/member")
@ApiOperation("获取单个成员统计信息")
public CommonResponse<Object> getMemberReport(Long memberId) {
MemberInfoVO memberReport = reportService.getMemberReport(memberId);
return CommonResponse.createBySuccess(memberReport);
}
@GetMapping("/report/manager")
@ApiOperation("手动触发websocket发送管理员统计信息")
public CommonResponse<Object> autoTriggerReport() {
reportService.reportHour();
return CommonResponse.createBySuccess();
}
}

@ -1,43 +0,0 @@
package com.baiye.modules.report.dao;
import com.baiye.modules.report.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);
}

@ -1,23 +0,0 @@
package com.baiye.modules.report.dao;
import com.baiye.modules.report.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);
}

@ -1,34 +0,0 @@
package com.baiye.modules.report.entity;
import cn.hutool.core.date.DatePattern;
import com.baiye.model.entity.BaseCallClueInfo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
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;
}

@ -1,37 +0,0 @@
package com.baiye.modules.report.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;
}

@ -1,24 +0,0 @@
package com.baiye.modules.report.entity.vo;
import cn.hutool.json.JSONObject;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* @author wjt
* @date 2021/12/13
*/
@Data
public class ReportMessageInfoVO implements Serializable {
private static final long serialVersionUID = -4455400757718138363L;
/**
* id
*/
private Integer code;
private Long userId;
private String type;
private List<TaskInfosVO> data;
private JSONObject totalData;
}

@ -1,22 +0,0 @@
package com.baiye.modules.report.service;
import com.baiye.modules.report.entity.vo.MemberInfoVO;
/**
* @author wjt
* @date 2021/12/10
*/
public interface ReportService {
/**
*
*/
void reportHour();
/**
*
*
* @param memberId
* @return
*/
MemberInfoVO getMemberReport(Long memberId);
}

@ -1,216 +0,0 @@
package com.baiye.modules.report.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
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.constant.DefaultNumberConstants;
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.modules.report.dao.CallClueRepository;
import com.baiye.modules.report.dao.ReportDayRepository;
import com.baiye.modules.report.entity.CallClueInfo;
import com.baiye.modules.report.entity.ReportDay;
import com.baiye.modules.report.entity.vo.MemberInfoVO;
import com.baiye.modules.report.entity.vo.ReportMessageInfoVO;
import com.baiye.modules.report.entity.vo.TaskInfosVO;
import com.baiye.modules.report.service.ReportService;
import com.baiye.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* @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() {
//所有线索总数
int total = 0;
//查询所有的拨打线索记录
List<CallClueInfo> all = callClueRepository.findAll();
Map<Long, List<CallClueInfo>> callClueInfoMap = new HashMap<>(16);
all.stream().collect(Collectors.groupingBy(CallClueInfo::getTaskId, Collectors.toList())).forEach(callClueInfoMap::put);
//查询所有的分配任务
TaskQueryCriteria taskQueryCriteria = new TaskQueryCriteria();
taskQueryCriteria.setIsDistribution(1);
ResponseEntity<Object> query = connectManageFeign.query(taskQueryCriteria);
JSONArray array = JSONUtil.parseArray(query.getBody());
if (CollUtil.isEmpty(array)) {
log.info("资源池里没有任务=");
return;
}
//发送websocket信息
ReportMessageInfoVO reportMessageInfoVO = new ReportMessageInfoVO();
List<TaskInfosVO> taskInfos = new ArrayList<>();
for (Object o : array) {
JSONObject jsonObject = (JSONObject) o;
Long id = jsonObject.getLong("id");
int clueTotal = jsonObject.getInt("totalNumber");
String taskName = jsonObject.getStr("taskName");
total += clueTotal;
if (callClueInfoMap.containsKey(id)) {
//获取今天产生的记录
List<CallClueInfo> callClueInfos = callClueInfoMap.get(id).stream().filter(c -> DateUtil.between(c.getCreateTime(), DateUtil.date(), DateUnit.DAY) == 0).collect(Collectors.toList());
JSONObject json = getMessageInfo(callClueInfos, clueTotal);
ReportDay reportDay = saveReport(id, clueTotal, json);
//任务保存到每天的数据
List<ReportDay> allByTaskId = reportDayRepository.findAllByTaskId(id);
allByTaskId.add(reportDay);
allByTaskId.sort(Comparator.comparing(ReportDay::getCreateTime));
//每个任务对应的所有日期的数据
TaskInfosVO taskInfo = new TaskInfosVO();
taskInfo.setTaskId(id);
taskInfo.setTaskName(taskName);
taskInfo.setData(allByTaskId);
taskInfos.add(taskInfo);
}
}
JSONObject totalData = getTotalData(all, total);
reportMessageInfoVO.setData(taskInfos);
reportMessageInfoVO.setTotalData(totalData);
sendAllManage(reportMessageInfoVO);
}
@Override
public MemberInfoVO getMemberReport(Long memberId) {
//查询此员工的所有线索
ResponseEntity<Object> objectResponseEntity = connectSourceFeign.queryMemberNum(memberId);
int total = (int) objectResponseEntity.getBody();
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;
}
/**
* 线
*
* @return
*/
private JSONObject getTotalData(List<CallClueInfo> all, Integer totalNum) {
JSONObject messageInfo = getMessageInfo(all, totalNum);
messageInfo.putOpt("totalNum", totalNum);
return messageInfo;
}
/**
*
*
* @param reportMessageInfoVO
* @return
*/
private void sendAllManage(ReportMessageInfoVO reportMessageInfoVO) {
try {
//todo 这里8为管理员 1为超级管理员。。后面改进
List<Long> roleIds = new ArrayList<>();
roleIds.add(1L);
roleIds.add(8L);
ResponseEntity<Object> adminInfo = connectManageFeign.getAdminInfo(roleIds);
JSONArray jsonArray = JSONUtil.parseArray(adminInfo.getBody());
for (Object o : jsonArray) {
JSONObject jsonObject = (JSONObject) o;
reportMessageInfoVO.setUserId(jsonObject.getLong("id"));
reportMessageInfoVO.setType("adminStatistics");
webSocketServer.sendMessage(reportMessageInfoVO);
}
} catch (Exception e) {
log.error("发生websocket异常 {}", e.getMessage());
}
}
/**
*
*
* @return
*/
private ReportDay saveReport(Long id, Integer clueTotal, JSONObject json) {
ReportDay reportDay = new ReportDay();
reportDay.setTaskId(id);
reportDay.setTotalNum(clueTotal);
reportDay.setTurnOnNum(json.getInt("turnOnNum"));
reportDay.setTurnOnRate(json.getDouble("turnOnRate"));
reportDay.setUsrRate(json.getDouble("usrRate"));
reportDay.setCreateTime(DateUtil.date());
if (DateUtil.hour(DateUtil.date(), true) == DefaultNumberConstants.TWENTY_THREE) {
//每天23点的统计 保存在数据库
reportDayRepository.save(reportDay);
}
return reportDay;
}
/**
*
*
* @param callClueInfos
* @param total
* @return
*/
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;
}
}

@ -1,10 +1,9 @@
package com.baiye.modules.elsaticjob.api;
import cn.hutool.core.bean.BeanUtil;
import com.baiye.http.CommonResponse;
import com.baiye.model.entity.BaseTimeTask;
import com.baiye.modules.elsaticjob.entity.AutoReminder;
import com.baiye.modules.elsaticjob.service.AutoReminderService;
import com.baiye.modules.timetask.entity.AutoReminder;
import com.baiye.modules.timetask.service.AutoReminderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@ -24,11 +23,7 @@ public class AutoReminderController {
@Resource
private AutoReminderService timeTaskService;
/**
*
*
* @param timeTask
*/
@PostMapping("/add")
@ApiOperation("新增")
public CommonResponse<Object> addTimeTask(@RequestBody BaseTimeTask timeTask) {
@ -36,4 +31,10 @@ public class AutoReminderController {
BeanUtil.copyProperties(timeTask, autoReminder);
return timeTaskService.addTimeTask(autoReminder);
}
@PostMapping("/update")
@ApiOperation("修改")
public CommonResponse<Object> updateTimeTask(@RequestBody AutoReminder timeTask) {
return timeTaskService.updateTimeTask(timeTask);
}
}

@ -1,8 +1,8 @@
package com.baiye.modules.elsaticjob.api;
package com.baiye.modules.timetask.api;
import com.baiye.modules.elsaticjob.entity.Job;
import com.baiye.modules.elsaticjob.entity.JobBriefInfo;
import com.baiye.modules.elsaticjob.service.ElasticJobService;
import com.baiye.modules.timetask.entity.Job;
import com.baiye.modules.timetask.entity.JobBriefInfo;
import com.baiye.modules.timetask.service.ElasticJobService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@ -1,6 +1,6 @@
package com.baiye.modules.elsaticjob.dao;
package com.baiye.modules.timetask.dao;
import com.baiye.modules.elsaticjob.entity.AutoReminder;
import com.baiye.modules.timetask.entity.AutoReminder;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
@ -32,4 +32,12 @@ public interface AutoReminderRepository extends JpaRepository<AutoReminder, Long
@Modifying
@Query(value = "update AutoReminder set status =?1 where id =?2")
void updateTimeTaskStatus(Integer status, Long id);
/**
* messageId
*
* @param messageId
* @return
*/
AutoReminder findAutoReminderByMessageId(Long messageId);
}

@ -1,4 +1,4 @@
package com.baiye.modules.elsaticjob.entity;
package com.baiye.modules.timetask.entity;
import cn.hutool.core.date.DatePattern;
import com.baiye.model.entity.BaseTimeTask;

@ -1,4 +1,4 @@
package com.baiye.modules.elsaticjob.entity;
package com.baiye.modules.timetask.entity;
import com.dangdang.ddframe.job.executor.handler.JobProperties;
import lombok.Data;

@ -1,4 +1,4 @@
package com.baiye.modules.elsaticjob.entity.jobInstance;
package com.baiye.modules.timetask.entity.jobInstance;
import org.springframework.stereotype.Component;

@ -1,4 +1,4 @@
package com.baiye.modules.elsaticjob.listener;
package com.baiye.modules.timetask.listener;
import com.dangdang.ddframe.job.executor.ShardingContexts;
import com.dangdang.ddframe.job.lite.api.listener.ElasticJobListener;

@ -1,7 +1,7 @@
package com.baiye.modules.elsaticjob.service;
package com.baiye.modules.timetask.service;
import com.baiye.http.CommonResponse;
import com.baiye.modules.elsaticjob.entity.AutoReminder;
import com.baiye.modules.timetask.entity.AutoReminder;
/**
* @author wujingtao
@ -15,4 +15,6 @@ public interface AutoReminderService {
* @return
*/
CommonResponse<Object> addTimeTask(AutoReminder timeTask);
CommonResponse<Object> updateTimeTask(AutoReminder timeTask);
}

@ -1,7 +1,7 @@
package com.baiye.modules.elsaticjob.service;
package com.baiye.modules.timetask.service;
import com.baiye.modules.elsaticjob.entity.Job;
import com.baiye.modules.elsaticjob.entity.JobBriefInfo;
import com.baiye.modules.timetask.entity.Job;
import com.baiye.modules.timetask.entity.JobBriefInfo;
import java.util.List;

@ -0,0 +1,111 @@
package com.baiye.modules.timetask.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
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.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.feign.ConnectManageFeign;
import com.baiye.http.CommonResponse;
import com.baiye.modules.timetask.dao.AutoReminderRepository;
import com.baiye.modules.timetask.entity.AutoReminder;
import com.baiye.modules.timetask.service.AutoReminderService;
import com.baiye.socket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
/**
* @author wujingtao
* @date 2022/01/05
*/
@Slf4j
@Service
public class AutoReminderServiceImpl implements AutoReminderService {
@Resource
private AutoReminderRepository timeTaskRepository;
@Resource
private WebSocketServer webSocketServer;
@Resource
private ConnectManageFeign connectManageFeign;
@Override
public CommonResponse<Object> addTimeTask(AutoReminder timeTask) {
if (timeTaskRepository.save(timeTask).getId() == null) {
log.error("method [addTimeTask] 保存定时任务失败");
return CommonResponse.createByErrorMessage("保存定时任务失败");
}
return CommonResponse.createBySuccess();
}
@Override
public CommonResponse<Object> updateTimeTask(AutoReminder timeTask) {
if (ObjectUtil.isNull(timeTask) || timeTask.getMessageId() == null) {
log.error("method [updateTimeTask] 参数不能为空");
return CommonResponse.createByErrorMessage("参数不能为空");
}
AutoReminder autoReminderByMessageId = timeTaskRepository.findAutoReminderByMessageId(timeTask.getMessageId());
BeanUtil.copyProperties(timeTask, autoReminderByMessageId);
timeTaskRepository.save(autoReminderByMessageId);
return CommonResponse.createBySuccess();
}
/**
* ,websocket
*/
@Transactional(rollbackFor = Exception.class)
public void runAutomaticReminder() {
//所有状态为0(可执行) 的自定义消息
List<AutoReminder> allByStatus = timeTaskRepository.findAllByStatus(DefaultNumberConstants.ZERO_NUMBER);
if (CollUtil.isEmpty(allByStatus)) {
return;
}
JSONObject webSocketData = new JSONObject();
webSocketData.putOpt("type", "");
webSocketData.putOpt("code", DefaultNumberConstants.TWO_HUNDRED);
JSONArray jsonArray = new JSONArray();
for (AutoReminder info : allByStatus) {
if (DateUtil.between(info.getExecuteTime(), DateUtil.date(), DateUnit.HOUR) == 0) {
JSONObject jsonObject = forwardMessage(info.getMessage());
webSocketData.putOpt("data", jsonObject);
try {
webSocketServer.sendMessage(JSONUtil.toJsonStr(webSocketData), String.valueOf(info.getUserId()));
} catch (Exception e) {
log.info("执行自提醒任务 id:{} 发送websocket失败 {}", info.getId(), e.getMessage());
continue;
}
jsonObject.putOpt("userId", info.getUserId());
jsonArray.add(jsonObject);
if (info.getIsRepeat() == DefaultNumberConstants.ZERO_NUMBER) {
timeTaskRepository.updateTimeTaskStatus(DefaultNumberConstants.ONE_NUMBER, info.getId());
}
}
}
try {
connectManageFeign.createMessage(JSONUtil.toJsonStr(jsonArray));
} catch (Exception e) {
log.info("Method 【runAutomaticReminder】 转发消息到 management 服务失败 {}", e.getMessage());
}
}
private JSONObject forwardMessage(String message) {
JSONObject json = new JSONObject();
json.putOpt("messageId", Long.valueOf(DateUtil.format(DateUtil.date(), "hhmmss") + RandomUtil.randomNumbers(4)));
json.putOpt("message", message);
return json;
}
}

@ -1,9 +1,9 @@
package com.baiye.modules.elsaticjob.service.impl;
package com.baiye.modules.timetask.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baiye.modules.elsaticjob.entity.Job;
import com.baiye.modules.elsaticjob.entity.JobBriefInfo;
import com.baiye.modules.elsaticjob.service.ElasticJobService;
import com.baiye.modules.timetask.entity.Job;
import com.baiye.modules.timetask.entity.JobBriefInfo;
import com.baiye.modules.timetask.service.ElasticJobService;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.executor.handler.JobProperties;

@ -3,16 +3,11 @@ package com.baiye.socket;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.feign.ConnectManageFeign;
import com.baiye.model.dto.SendWebSocketDTO;
import com.baiye.model.enums.WebSocketEnums;
import com.baiye.modules.report.entity.vo.ReportMessageInfoVO;
import com.baiye.modules.report.service.impl.ReportServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
@ -30,17 +25,10 @@ import java.util.concurrent.atomic.AtomicInteger;
@ServerEndpoint(value = "/task/prosperous/{userId}")
public class WebSocketServer {
private static String user;
@Resource
private ReportServiceImpl reportServiceImpl;
@Resource
private ConnectManageFeign connectManageFeign;
private static WebSocketServer webSocketServer;
@PostConstruct
public void init() {
log.info("websocket 加载");
webSocketServer = this;
}
private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0);
@ -87,28 +75,6 @@ public class WebSocketServer {
@OnMessage
public void onMessage(String message, Session session) {
log.info("来自客户端的消息:{}", message);
JSONObject jsonObject = JSONUtil.parseObj(message);
//todo 后面建常量类
String adminStatistics = "adminStatistics";
String type = "type";
if (adminStatistics.equals(jsonObject.getStr(type))) {
webSocketServer.reportServiceImpl.reportHour();
}
switch (WebSocketEnums.find(jsonObject.getStr(type))) {
case DefaultNumberConstants.TWO_NUMBER:
connectManageFeign.changeMessage(message);
break;
case DefaultNumberConstants.THREE_NUMBER:
connectManageFeign.userMessageRead(message);
break;
case DefaultNumberConstants.FIVE_NUMBER:
connectManageFeign.createMessage(message);
break;
default:
break;
}
}
/**
@ -170,30 +136,12 @@ public class WebSocketServer {
}
}
public void sendMessage(ReportMessageInfoVO reportMessageInfoVO) throws IOException {
Session session = null;
for (String key : SESSIONS.keySet()) {
if (key.equals(String.valueOf(reportMessageInfoVO.getUserId()))) {
session = SESSIONS.get(key);
break;
}
}
if (session != null) {
reportMessageInfoVO.setCode(DefaultNumberConstants.TWO_HUNDRED);
session.getBasicRemote().sendText(JSONUtil.toJsonStr(reportMessageInfoVO));
} else {
log.warn("没有找到你指定ID的会话{}", reportMessageInfoVO.getUserId());
}
}
public void sendMessage(SendWebSocketDTO.SendMessage data, List<Long> ids) throws IOException {
for (long id : ids) {
if (SESSIONS.containsKey(String.valueOf(id))) {
Session session = SESSIONS.get(String.valueOf(id));
data.setCode(DefaultNumberConstants.TWO_HUNDRED);
log.info(" 发送给 id{} 的websocket 信息为:{}", id, data);
session.getBasicRemote().sendText(JSONUtil.toJsonStr(data));
} else {
log.warn("没有找到你指定ID的会话{}", id);

@ -116,4 +116,10 @@ public class ClueController {
public void exportClueList(HttpServletResponse response, ClueQueryCriteria clueQueryCriteria) {
clueService.exportClueList(response, clueQueryCriteria);
}
@ApiOperation("根据小组id统计小组资源数")
@GetMapping("/count")
public ResponseEntity<Object> countClueByGroupId(@RequestParam("groupId") Long groupId) {
return new ResponseEntity<>(clueService.countClueByGroupId(groupId), HttpStatus.OK);
}
}

@ -4,9 +4,11 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baiye.model.dto.ClueDto;
import com.baiye.model.dto.ClueQueryCriteria;
import com.baiye.util.AESUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@ -26,6 +28,10 @@ public class ClueJpa {
@PersistenceContext
EntityManager entityManager;
@Value("${aes.secret}")
private String secret;
/**
* null
*/
@ -125,7 +131,11 @@ public class ClueJpa {
clueDto.setMemberStatus((Integer) row.get("memberStatus"));
clueDto.setName((String) row.get("name"));
clueDto.setCreateTime((Date) row.get("createTime"));
clueDto.setNid((String) row.get("nid"));
String phone = (String) row.get("nid");
if (StringUtils.isNotBlank(phone)) {
String nid = AESUtils.decrypt(phone, secret);
clueDto.setNid(nid);
}
clueDto.setWx((String) row.get("wx"));
clueDto.setAddress((String) row.get("address"));
clueDto.setRemark((String) row.get("remark"));

@ -66,6 +66,13 @@ public interface ClueMiddleRepository extends JpaRepository<ClueMiddle, Long>, J
*/
Long countByMemberId(Long memberId);
/**
*
* @param organizeId
* @return
*/
Integer countByOrganizeId(Long organizeId);
/**
*
*

@ -123,4 +123,11 @@ public interface ClueService {
* @return
*/
Set<Long> findMemberIdList(ClueMiddle clueMiddle);
/**
*
* @param groupId
* @return
*/
Integer countClueByGroupId(Long groupId);
}

@ -248,4 +248,9 @@ public class ClueServiceImpl implements ClueService {
}
return null;
}
@Override
public Integer countClueByGroupId(Long groupId) {
return clueMiddleRepository.countByOrganizeId(groupId);
}
}

@ -34,7 +34,7 @@
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>utf- </charset>
<charset>utf-8 </charset>
</encoder>
<!-- 不写TRACE DEBUG -->

Loading…
Cancel
Save