diff --git a/ad-platform-common/pom.xml b/ad-platform-common/pom.xml index 14456a2c..ae876bcd 100644 --- a/ad-platform-common/pom.xml +++ b/ad-platform-common/pom.xml @@ -18,6 +18,17 @@ + + com.dangdang + elastic-job-lite-core + 2.1.5 + + + guava + com.google.guava + + + org.springframework.boot diff --git a/ad-platform-common/src/main/java/com/baiye/exception/ElasticException.java b/ad-platform-common/src/main/java/com/baiye/exception/ElasticException.java new file mode 100644 index 00000000..99f09050 --- /dev/null +++ b/ad-platform-common/src/main/java/com/baiye/exception/ElasticException.java @@ -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()); + } +} diff --git a/ad-platform-gateway/src/main/resources/application.yml b/ad-platform-gateway/src/main/resources/application.yml index e6965059..674c7e95 100644 --- a/ad-platform-gateway/src/main/resources/application.yml +++ b/ad-platform-gateway/src/main/resources/application.yml @@ -24,7 +24,12 @@ spring: - Path=/api-source/** filters: - StripPrefix=1 - + - id: platform-task + uri: lb://ad-platform-task + predicates: + - Path=/api-task/** + filters: + - StripPrefix=1 hystrix: command: default: diff --git a/ad-platform-pojo/pom.xml b/ad-platform-pojo/pom.xml index 9d34a48e..6e899e1a 100644 --- a/ad-platform-pojo/pom.xml +++ b/ad-platform-pojo/pom.xml @@ -18,6 +18,11 @@ + + com.baiye + ad-platform-common + 1.0-SNAPSHOT + org.springframework.boot spring-boot-starter-data-jpa diff --git a/ad-platform-pojo/src/main/java/com/baiye/model/dto/ClueQueryCriteria.java b/ad-platform-pojo/src/main/java/com/baiye/model/dto/ClueQueryCriteria.java index 0d90d626..bb16a0df 100644 --- a/ad-platform-pojo/src/main/java/com/baiye/model/dto/ClueQueryCriteria.java +++ b/ad-platform-pojo/src/main/java/com/baiye/model/dto/ClueQueryCriteria.java @@ -3,12 +3,11 @@ package com.baiye.model.dto; import com.baiye.annotation.Query; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import org.springframework.data.domain.Pageable; -import javax.persistence.Column; /** * 资源clue公共查询类 + * @author wjt */ @Data public class ClueQueryCriteria { diff --git a/ad-platform-pojo/src/main/java/com/baiye/model/entity/BaseCallClueInfo.java b/ad-platform-pojo/src/main/java/com/baiye/model/entity/BaseCallClueInfo.java new file mode 100644 index 00000000..adc0b8ef --- /dev/null +++ b/ad-platform-pojo/src/main/java/com/baiye/model/entity/BaseCallClueInfo.java @@ -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; +} diff --git a/ad-platform-pojo/src/main/java/com/baiye/model/enums/CallStatusEnum.java b/ad-platform-pojo/src/main/java/com/baiye/model/enums/CallStatusEnum.java new file mode 100644 index 00000000..0463a2a6 --- /dev/null +++ b/ad-platform-pojo/src/main/java/com/baiye/model/enums/CallStatusEnum.java @@ -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; + } +} diff --git a/manage/ad-platform-management/pom.xml b/manage/ad-platform-management/pom.xml index 4877e965..e010a8c9 100644 --- a/manage/ad-platform-management/pom.xml +++ b/manage/ad-platform-management/pom.xml @@ -30,7 +30,6 @@ ad-platform-common 1.0-SNAPSHOT - com.baiye ad-platform-pojo @@ -109,6 +108,10 @@ org.springframework.cloud spring-cloud-starter-openfeign + + com.spring4all + swagger-spring-boot-starter + diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/impl/DeptServiceImpl.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/impl/DeptServiceImpl.java index 073a9a75..ab5faf5e 100644 --- a/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/impl/DeptServiceImpl.java +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/impl/DeptServiceImpl.java @@ -203,7 +203,7 @@ @Override public List getSuperior(DeptDto deptDto, List depts) { - if (deptDto.getPid() == null) { + if (deptDto.getPid() == null || deptDto.getPid() == DefaultNumberConstants.ZERO_NUMBER) { depts.addAll(deptRepository.findByPidIsNull()); return deptMapper.toDto(depts); } diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/mapstruct/TaskMapper.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/mapstruct/TaskMapper.java index 92477ff8..95832ea4 100644 --- a/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/mapstruct/TaskMapper.java +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/system/service/mapstruct/TaskMapper.java @@ -16,9 +16,7 @@ package com.baiye.modules.system.service.mapstruct; import com.baiye.model.base.BaseMapper; -import com.baiye.modules.system.domain.Dept; import com.baiye.modules.system.domain.Task; -import com.baiye.modules.system.service.dto.DeptDto; import com.baiye.modules.system.service.dto.TaskDto; import org.mapstruct.Mapper; import org.mapstruct.ReportingPolicy; diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/api/DoubleCallController.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/api/DoubleCallController.java new file mode 100644 index 00000000..ad94dc28 --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/api/DoubleCallController.java @@ -0,0 +1,84 @@ +package com.baiye.modules.telemarkting.api; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +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; +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.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +/** + * @author wjt + * @date 2021/12/14 + */ +@Slf4j +@RestController +@RequestMapping("/api") +@Api(tags = "对接双呼") +public class DoubleCallController { + @Resource + private DoubleCallService doubleCallService; + + @PostMapping("/double/req") + @ApiOperation("请求接入双呼") + public CommonResponse doubleCallReq(@RequestBody DoubleCallReqDTO doubleCallReq) { + if (ObjectUtil.isEmpty(doubleCallReq)) { + return CommonResponse.createByError(); + } + return doubleCallService.doubleCallReq(doubleCallReq); + } + + @PostMapping("/back/cdrUrl") + @ApiOperation("双呼系统回调话单") + public CommonResponse doubleCallBack(@RequestBody String json) { + try { + DoubleCallBackDTO doubleCallReq = JSONUtil.toBean(json, DoubleCallBackDTO.class); + if (ObjectUtil.isEmpty(doubleCallReq) || StrUtil.isEmpty(doubleCallReq.getSessionId())) { + return CommonResponse.createByErrorMessage("参数为空"); + } + log.info("=======双呼回调: {}", doubleCallReq); + doubleCallService.doubleCallBack(doubleCallReq); + } catch (Exception e) { + log.error("双呼回调话单错误 参数 :{}", json); + log.error("双呼回调话单错误,数据解析错误 :{}", e.getMessage()); + return CommonResponse.createByError(); + } + return CommonResponse.createBySuccess(); + } + + @PostMapping("/back/status") + @ApiOperation("双呼系统回调状态") + public CommonResponse doubleCallBackStatus(@RequestBody String json) { + try { + DoubleCallBackStatusDTO doubleCallBack = JSONUtil.toBean(json, DoubleCallBackStatusDTO.class); + if (ObjectUtil.isEmpty(doubleCallBack) || StrUtil.isEmpty(doubleCallBack.getSessionId())) { + return CommonResponse.createByErrorMessage("参数为空"); + } + log.info("解析状态后的对象 :{}", doubleCallBack); + doubleCallService.doubleCallBackStatus(doubleCallBack); + } catch (Exception e) { + log.error("双呼回调状态错误 参数 :{}", json); + log.error("双呼回调状态错误,数据解析错误 :{}", e.getMessage()); + return CommonResponse.createByError(); + } + return CommonResponse.createBySuccess(); + } + + @GetMapping("/double/stop") + @ApiOperation("挂断呼叫") + public CommonResponse doubleCallStop(String sessionId) { + if (StrUtil.isEmpty(sessionId)) { + return CommonResponse.createByErrorMessage("SESSION_ID不存在"); + } + return doubleCallService.doubleCallStop(sessionId); + } +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/dao/CallClueRepository.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/dao/CallClueRepository.java new file mode 100644 index 00000000..5fdccf1f --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/dao/CallClueRepository.java @@ -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, JpaSpecificationExecutor { + /** + * 主键查询 + * + * @param id + * @return + */ + CallClueInfo findByClueId(Long id); + + /** + * 按条件查询 + * + * @param memberId + * @return + */ + @Query("select d from CallClueInfo d where d.memberId=?1 ") + List selectByMember(Long memberId); +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/dao/DoubleCallRepository.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/dao/DoubleCallRepository.java new file mode 100644 index 00000000..2f126c76 --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/dao/DoubleCallRepository.java @@ -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, JpaSpecificationExecutor { + /** + * 根据id查询 + * + * @param id + * @return + */ + DoubleCallInfo findById(String id); + + /** + * 按条件查询 + * + * @param memberId + * @return + */ + @Query("select d from DoubleCallInfo d where d.memberId=?1 ") + List selectByMemberAndStatus(Long memberId); +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/CallClueInfo.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/CallClueInfo.java new file mode 100644 index 00000000..0804318a --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/CallClueInfo.java @@ -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; +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/DoubleCallInfo.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/DoubleCallInfo.java new file mode 100644 index 00000000..1939fbce --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/DoubleCallInfo.java @@ -0,0 +1,107 @@ +package com.baiye.modules.telemarkting.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.*; +import java.io.Serializable; +import java.util.Date; + +/** + * @author wjt + * @date 2021/12/06 + */ +@Data +@Entity +@Table(name = "tb_double_call") +@EntityListeners(AuditingEntityListener.class) +public class DoubleCallInfo 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; +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallBackDTO.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallBackDTO.java new file mode 100644 index 00000000..9e850112 --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallBackDTO.java @@ -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; +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallBackStatusDTO.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallBackStatusDTO.java new file mode 100644 index 00000000..61f7c3ad --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallBackStatusDTO.java @@ -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; +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallReqDTO.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallReqDTO.java new file mode 100644 index 00000000..1902334f --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallReqDTO.java @@ -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; +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallSystemDTO.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallSystemDTO.java new file mode 100644 index 00000000..61a59f40 --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/entity/dto/DoubleCallSystemDTO.java @@ -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; +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/httpRequest/CallReq.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/httpRequest/CallReq.java new file mode 100644 index 00000000..eff80442 --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/httpRequest/CallReq.java @@ -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(); + } +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/service/DoubleCallService.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/service/DoubleCallService.java new file mode 100644 index 00000000..3bd716d6 --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/service/DoubleCallService.java @@ -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 doubleCallReq(DoubleCallReqDTO doubleCallReq); + + /** + * 回调话单 + * + * @param doubleCallBack + */ + void doubleCallBack(DoubleCallBackDTO doubleCallBack); + + /** + * 回调状态 + * + * @param doubleCallBackStatus + */ + void doubleCallBackStatus(DoubleCallBackStatusDTO doubleCallBackStatus); + + /** + * 停止通话 + * + * @param sessionId + * @return + */ + CommonResponse doubleCallStop(String sessionId); +} diff --git a/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/service/impl/DoubleCallServiceImpl.java b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/service/impl/DoubleCallServiceImpl.java new file mode 100644 index 00000000..3c7ef05b --- /dev/null +++ b/manage/ad-platform-management/src/main/java/com/baiye/modules/telemarkting/service/impl/DoubleCallServiceImpl.java @@ -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 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 doubleCallStop(String sessionId) { + if (callReq.stopReq(sessionId)) { + return CommonResponse.createBySuccess(); + } + return CommonResponse.createByError(); + } +} diff --git a/manage/ad-platform-management/src/main/resources/config/application.yml b/manage/ad-platform-management/src/main/resources/config/application.yml index e1f8e524..fd212683 100644 --- a/manage/ad-platform-management/src/main/resources/config/application.yml +++ b/manage/ad-platform-management/src/main/resources/config/application.yml @@ -1,5 +1,5 @@ server: - port: 8000 + port: 8866 spring: application: @@ -15,7 +15,9 @@ spring: repositories: enabled: false - +ribbon: + ReadTimeout: 3000 + ConnectTimeout: 3000 #配置 Jpa jpa: @@ -53,3 +55,12 @@ code: #密码加密传输,前端公钥加密,后端私钥解密 rsa: private_key: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKLhn7fPqFSK9z3Ao4yFFisDO8YV1dOn1I3wpwj1IIu3Z7vkaHyynBf7eF8fo86EQRvnJIo3jVO2jUw5Lor2OYcZVK72oxD5LIULVYI/eXJogzd1C+tJ5IHC7dmTJ37qfjP9VV3mDWlsRusdCoVPE2xUI13H4bPOCE4DyyeldXlFAgMBAAECgYBakWx3D5+AyvipPKl0JDhsWFLvVQrdss+M0Uh/wZWEOsoSfvHejI4hA7It6nDyDzYI5uC5fiQ2bSZqQM1xdXIMmq4F0WM2+ni4Q/bYbaLt9UDGs6GXwHcg3gOTBJoSJq0SZxBpflxbfVOj63ITehTl51q0FvaedxWl63hf6bikQQJBANT3s1usMZmubYxQPLrBeK1mcXG1JxwKDK6n7bJnlBeZy1GCUZ7bwBgr32gRvUXtgqrzT3IyZlld5cUScX601TUCQQDDyxVAPExwbpxD0Ao7CZE9LRYC8YaMQ46NENqaIhnmhMa4vqoTky8t2nLZITmk0EqecTBt/Io+37+X/KCHD+XRAkAraGmIb+qUNndhuCEIt9KPFWheEtxr3KiFGPlb+by3qsNEU9mrFYNr6dVZcvQvQp/1lC5HSnqOEJN6va2gc99ZAkEAnYtF+EAMydNXDgHSmZqjMXSb55Zsy2R4ye2r2KZj7Ocd9/4DYGjoZ58FFs3zUjkAMemmLHouy1TDGAsBKGyUYQJBAJ1io1DxuejCE+sN/bu4Y2S7oQ2Mpfjh7jRYGruDzhdqVnnLxf0spaqJZ5HekQz3uMpkQQGkcN1MZZcRpoWJ7XU= + +double: + call: + reqUrl: http://ax.hzdaba.cn/callback/Accounts/dbby_hangzhoubaiyehl/Hw/CallBack + appid: app1 + companyName: 杭州百业互联科技有限公司 + cdrUrl: http://118.178.137.129:8866/call/back/cdrUrl + statusUrl: http://118.178.137.129:8866/call/back/status + stopUrl: http://ax.hzdaba.cn/callback/Accounts/dbby_hangzhoubaiyehl/Hw/CallBackStop \ No newline at end of file diff --git a/manage/ad-platform-task/pom.xml b/manage/ad-platform-task/pom.xml index cca82ab8..5b194336 100644 --- a/manage/ad-platform-task/pom.xml +++ b/manage/ad-platform-task/pom.xml @@ -30,5 +30,79 @@ ad-platform-pojo 1.0-SNAPSHOT + + + + + + + + + + + + + org.springframework.boot + spring-boot-configuration-processor + 2.3.2.RELEASE + true + + + mysql + mysql-connector-java + + + org.springframework.boot + spring-boot-starter-jdbc + + + cn.hutool + hutool-all + 5.7.13 + + + com.alibaba + druid-spring-boot-starter + + + org.apache.curator + curator-framework + 2.12.0 + + + org.apache.curator + curator-client + 2.12.0 + + + guava + com.google.guava + + + + + org.apache.curator + curator-recipes + 2.12.0 + + + com.spring4all + swagger-spring-boot-starter + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.boot + spring-boot-starter-websocket + \ No newline at end of file diff --git a/manage/ad-platform-task/src/main/java/com/baiye/AdPlatformTaskApplication.java b/manage/ad-platform-task/src/main/java/com/baiye/AdPlatformTaskApplication.java index a5ca1fa7..808802b8 100644 --- a/manage/ad-platform-task/src/main/java/com/baiye/AdPlatformTaskApplication.java +++ b/manage/ad-platform-task/src/main/java/com/baiye/AdPlatformTaskApplication.java @@ -1,7 +1,11 @@ package com.baiye; +import com.spring4all.swagger.EnableSwagger2Doc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; /** * 广告平台任务应用程序 @@ -9,6 +13,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; * @author q * @date 2021/11/11 */ +@EnableSwagger2Doc +@EnableJpaAuditing +@EnableFeignClients +@EnableDiscoveryClient @SpringBootApplication public class AdPlatformTaskApplication { diff --git a/manage/ad-platform-task/src/main/java/com/baiye/api/ElasticJobController.java b/manage/ad-platform-task/src/main/java/com/baiye/api/ElasticJobController.java new file mode 100644 index 00000000..38998c51 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/api/ElasticJobController.java @@ -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 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); + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/api/ReportController.java b/manage/ad-platform-task/src/main/java/com/baiye/api/ReportController.java new file mode 100644 index 00000000..178ab05b --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/api/ReportController.java @@ -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 getMemberReport(Long memberId) { + MemberInfoVO memberReport = reportService.getMemberReport(memberId); + return CommonResponse.createBySuccess(memberReport); + } + + @GetMapping("/report/manager") + public CommonResponse getReportHour() { + reportService.reportHour(); + return CommonResponse.createBySuccess(); + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/config/JobParserAutoConfiguration.java b/manage/ad-platform-task/src/main/java/com/baiye/config/JobParserAutoConfiguration.java new file mode 100644 index 00000000..cbb2c12e --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/config/JobParserAutoConfiguration.java @@ -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); + } + +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/config/SimpleJobAutoConfig.java b/manage/ad-platform-task/src/main/java/com/baiye/config/SimpleJobAutoConfig.java new file mode 100644 index 00000000..ddf18258 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/config/SimpleJobAutoConfig.java @@ -0,0 +1,131 @@ +package com.baiye.config; + +import com.baiye.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; +import com.dangdang.ddframe.job.executor.handler.JobProperties; +import com.dangdang.ddframe.job.lite.api.JobScheduler; +import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration; +import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter; +import org.springframework.beans.BeansException; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; + +import javax.annotation.Resource; +import java.util.Map; + +/** + * @author wjt + * @date 2021/12/15 + */ +@Configuration +@ConditionalOnBean(CoordinatorRegistryCenter.class) +@AutoConfigureAfter(JobParserAutoConfiguration.class) +public class SimpleJobAutoConfig implements ApplicationContextAware { + private Environment environment; + private final String prefix = "elastic.job."; + @Resource + private CoordinatorRegistryCenter center; + + @Override + public void setApplicationContext(ApplicationContext ctx) throws BeansException { + environment = ctx.getEnvironment(); + Map beanMap = ctx.getBeansWithAnnotation(ElasticSimpleJob.class); + for (Object bean : beanMap.values()) { + Class cls = bean.getClass(); + String jobTypeName = cls.getInterfaces()[0].getSimpleName(); + if ("SimpleJob".equals(jobTypeName)) { + ElasticSimpleJob annotation = AnnotationUtils.findAnnotation(cls, ElasticSimpleJob.class); + String jobClass = cls.getName(); + String jobName = annotation.jobName(); + String cron = getEnvironmentStringValue(jobName, "cron", annotation.cron()); + int shardingTotalCount = getEnvironmentIntValue(jobName, "shardingTotalCount", annotation.shardingTotalCount()); + String shardingItemParameters = getEnvironmentStringValue(jobName, "shardingItemParameters", annotation.shardingItemParameters()); + String jobParameter = getEnvironmentStringValue(jobName, "jobParameter", annotation.jobParameter()); + boolean monitorExecution = getEnvironmentBooleanValue(jobName, "monitorExecution", annotation.monitorExecution()); + int maxTimeDiffSeconds = getEnvironmentIntValue(jobName, "maxTimeDiffSeconds", annotation.maxTimeDiffSeconds()); + int monitorPort = getEnvironmentIntValue(jobName, "monitorPort", annotation.monitorPort()); + boolean failover = getEnvironmentBooleanValue(jobName, "failover", annotation.failover()); + boolean misfire = getEnvironmentBooleanValue(jobName, "misfire", annotation.misfire()); + String jobShardingStrategyClass = getEnvironmentStringValue(jobName, "jobShardingStrategyClass", annotation.jobShardingStrategyClass()); + String description = getEnvironmentStringValue(jobName, "description", annotation.description()); + int reconcileIntervalMinutes = getEnvironmentIntValue(jobName, "reconcileIntervalMinutes", annotation.reconcileIntervalMinutes()); + String jobExceptionHandler = getEnvironmentStringValue(jobName, "jobExceptionHandler", annotation.jobExceptionHandler()); + String executorServiceHandler = getEnvironmentStringValue(jobName, "executorServiceHandler", annotation.executorServiceHandler()); + boolean overwrite = getEnvironmentBooleanValue(jobName, "overwrite", annotation.overwrite()); + // 核心配置 + JobCoreConfiguration coreConfig = + JobCoreConfiguration.newBuilder(jobName, cron, shardingTotalCount) + .shardingItemParameters(shardingItemParameters) + .description(description) + .failover(failover) + .jobParameter(jobParameter) + .misfire(misfire) + .jobProperties(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), jobExceptionHandler) + .jobProperties(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER.getKey(), executorServiceHandler) + .build(); + JobTypeConfiguration typeConfig = new SimpleJobConfiguration(coreConfig, jobClass); + LiteJobConfiguration jobConfig = LiteJobConfiguration.newBuilder(typeConfig) + .overwrite(overwrite) + .monitorPort(monitorPort) + .monitorExecution(monitorExecution) + .maxTimeDiffSeconds(maxTimeDiffSeconds) + .jobShardingStrategyClass(jobShardingStrategyClass) + .reconcileIntervalMinutes(reconcileIntervalMinutes) + .build(); + new JobScheduler(center, jobConfig).init(); + } + } + } + + /** + * 获取配置中的任务属性值,environment没有就用注解中的值 + * + * @param jobName 任务名称 + * @param fieldName 属性名称 + * @param defaultValue 默认值 + * @return + */ + private String getEnvironmentStringValue(String jobName, String fieldName, String defaultValue) { + String key = prefix + jobName + "." + fieldName; + String value = environment.getProperty(key); + if (StringUtils.hasText(value)) { + return value; + } + return defaultValue; + } + + private int getEnvironmentIntValue(String jobName, String fieldName, int defaultValue) { + String key = prefix + jobName + "." + fieldName; + String value = environment.getProperty(key); + if (StringUtils.hasText(value)) { + return Integer.parseInt(value); + } + return defaultValue; + } + + private long getEnvironmentLongValue(String jobName, String fieldName, long defaultValue) { + String key = prefix + jobName + "." + fieldName; + String value = environment.getProperty(key); + if (StringUtils.hasText(value)) { + return Long.parseLong(value); + } + return defaultValue; + } + + private boolean getEnvironmentBooleanValue(String jobName, String fieldName, boolean defaultValue) { + String key = prefix + jobName + "." + fieldName; + String value = environment.getProperty(key); + if (StringUtils.hasText(value)) { + return Boolean.parseBoolean(value); + } + return defaultValue; + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/config/WebSocketConfig.java b/manage/ad-platform-task/src/main/java/com/baiye/config/WebSocketConfig.java new file mode 100644 index 00000000..82d5716f --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/config/WebSocketConfig.java @@ -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(); + } +} \ No newline at end of file diff --git a/manage/ad-platform-task/src/main/java/com/baiye/config/ZookeeperProperties.java b/manage/ad-platform-task/src/main/java/com/baiye/config/ZookeeperProperties.java new file mode 100644 index 00000000..647cbe85 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/config/ZookeeperProperties.java @@ -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; +} \ No newline at end of file diff --git a/manage/ad-platform-task/src/main/java/com/baiye/dao/CallClueRepository.java b/manage/ad-platform-task/src/main/java/com/baiye/dao/CallClueRepository.java new file mode 100644 index 00000000..b33c8905 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/dao/CallClueRepository.java @@ -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, JpaSpecificationExecutor { + /** + * 主键查询 + * + * @param id + * @return + */ + CallClueInfo findByClueId(Long id); + + /** + * 按条件查询 + * + * @param memberId + * @return + */ + @Query("select d from CallClueInfo d where d.memberId=?1 ") + List selectByMember(Long memberId); + + /** + * 按条件查询 + * + * @param taskId + * @param day + * @return + */ + @Query("select d from CallClueInfo d where d.taskId=?1 and concat(d.createTime,'') =?2 ") + List selectByCondition(Long taskId, String day); +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/dao/ReportDayRepository.java b/manage/ad-platform-task/src/main/java/com/baiye/dao/ReportDayRepository.java new file mode 100644 index 00000000..65099396 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/dao/ReportDayRepository.java @@ -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, JpaSpecificationExecutor { + /** + * 通过任务id 查询所有的日报 + * + * @param taskId + * @return + */ + List findAllByTaskId(Long taskId); +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/entity/CallClueInfo.java b/manage/ad-platform-task/src/main/java/com/baiye/entity/CallClueInfo.java new file mode 100644 index 00000000..89d1df88 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/entity/CallClueInfo.java @@ -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; +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/entity/Job.java b/manage/ad-platform-task/src/main/java/com/baiye/entity/Job.java new file mode 100644 index 00000000..c6153c08 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/entity/Job.java @@ -0,0 +1,106 @@ +package com.baiye.entity; + +import com.dangdang.ddframe.job.executor.handler.JobProperties; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author wjt + * @date 2021/11/26 + */ +@Data +public class Job implements Serializable { + private static final long serialVersionUID = -7135891833447229851L; + + public Job() { + } + + /** + * 任务名称 + */ + @NotNull + private String jobName; + /** + * 任务类型 + */ + private String jobType; + /** + * 任务实例类路径 + */ + @NotNull + + private String jobClass; + /** + * 执行时间表达式 + */ + @NotNull + private String cron; + /** + * 总分片数 + */ + private int shardingTotalCount = 1; + /** + * 分片序列号/参数对照 多个键值对用逗号分隔 + * 分片序列号从0开始,不可大于或等于作业分片总数 + * 如0=a,1=b,2=c + */ + private String shardingItemParameters = ""; + /** + * 自定义的参数,可通过传递该参数为作业调度的业务方法传参 + */ + private String jobParameter = ""; + /** + * 监控作业运行时状态 + * 每次作业执行时间和间隔时间均较长的情况,建议监控作业运行时状态,可保证数据不会重复选取 + */ + private boolean monitorExecution = true; + /** + * 是否流式处理数据 + * 如果非流式处理数据, 则处理数据完成后作业结束 + */ + private boolean streamingProcess = false; + /** + * 最大允许的本机与注册中心的时间误差秒数 + * >配置为-1表示不校验时间误差 + */ + private int maxTimeDiffSeconds = -1; + /** + * 作业监控端口 + */ + private int monitorPort = -1; + /** + * 是否开启任务执行失效转移,开启表示如果作业在一次任务执行中途宕机,允许将该次未完成的任务在另一作业节点上补偿执行 + */ + private boolean failover = false; + /** + * 是否开启错过任务重新执行 + */ + private boolean misfire = false; + /** + * 作业分片策略实现类全路径,默认使用平均分配策略 + */ + private String jobShardingStrategyClass = ""; + /** + * 作业描述 + */ + private String description = ""; + + /** + * 脚本型作业执行命令行 + */ + private String scriptCommandLine = ""; + /** + * 修复作业服务器不一致状态服务调度间隔时间,配置为小于1的任意值表示不执行修复,单位:分钟 + */ + private int reconcileIntervalMinutes = 10; + /** + * 异常定义 + */ + private Map jobProperties = new LinkedHashMap(JobProperties.JobPropertiesEnum.values().length, 1.0F); + + private Boolean overwrite = true; +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/entity/JobBriefInfo.java b/manage/ad-platform-task/src/main/java/com/baiye/entity/JobBriefInfo.java new file mode 100644 index 00000000..51d4ac70 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/entity/JobBriefInfo.java @@ -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 { + 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() { + } + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/entity/ReportDay.java b/manage/ad-platform-task/src/main/java/com/baiye/entity/ReportDay.java new file mode 100644 index 00000000..7f48911e --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/entity/ReportDay.java @@ -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; + +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/entity/jobInstance/ElasticSimpleJob.java b/manage/ad-platform-task/src/main/java/com/baiye/entity/jobInstance/ElasticSimpleJob.java new file mode 100644 index 00000000..e77f8bc7 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/entity/jobInstance/ElasticSimpleJob.java @@ -0,0 +1,101 @@ +package com.baiye.entity.jobInstance; + +import org.springframework.stereotype.Component; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author wjt + * @date 2021/12/15 + */ +@Component +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ElasticSimpleJob { + /** + * 任务名称 + */ + String jobName(); + + /** + * 执行时间表达式 + */ + String cron() default ""; + + /** + * 总分片数 + */ + int shardingTotalCount() default 1; + + /** + * 分片序列号/参数对照 多个键值对用逗号分隔 + * 分片序列号从0开始,不可大于或等于作业分片总数 + * 如0=a,1=b,2=c + */ + String shardingItemParameters() default ""; + + /** + * 自定义的参数,可通过传递该参数为作业调度的业务方法传参 + */ + String jobParameter() default ""; + + /** + * 监控作业运行时状态 + * 每次作业执行时间和间隔时间均较长的情况,建议监控作业运行时状态,可保证数据不会重复选取 + */ + boolean monitorExecution() default true; + + /** + * 最大允许的本机与注册中心的时间误差秒数 + * >配置为-1表示不校验时间误差 + */ + int maxTimeDiffSeconds() default -1; + + /** + * 作业监控端口 + */ + int monitorPort() default -1; + + /** + * 是否开启任务执行失效转移,开启表示如果作业在一次任务执行中途宕机,允许将该次未完成的任务在另一作业节点上补偿执行 + */ + boolean failover() default false; + + /** + * 是否开启错过任务重新执行 + */ + boolean misfire() default false; + + /** + * 作业分片策略实现类全路径,默认使用平均分配策略 + */ + String jobShardingStrategyClass() default ""; + + /** + * 作业描述 + */ + String description() default ""; + + + /** + * 修复作业服务器不一致状态服务调度间隔时间,配置为小于1的任意值表示不执行修复,单位:分钟 + */ + int reconcileIntervalMinutes() default 10; + + /** + * 异常定义 + */ + String jobExceptionHandler() default "com.baiye.exception.ElasticException"; + + /** + * 自定义业务处理线程池 + * + * @return + */ + String executorServiceHandler() default "com.dangdang.ddframe.job.executor.handler.impl.DefaultExecutorServiceHandler"; + + boolean overwrite() default true; +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/entity/vo/MemberInfoVO.java b/manage/ad-platform-task/src/main/java/com/baiye/entity/vo/MemberInfoVO.java new file mode 100644 index 00000000..38a338f6 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/entity/vo/MemberInfoVO.java @@ -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; +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/entity/vo/ReportMessageInfoVO.java b/manage/ad-platform-task/src/main/java/com/baiye/entity/vo/ReportMessageInfoVO.java new file mode 100644 index 00000000..c0b5b343 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/entity/vo/ReportMessageInfoVO.java @@ -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 list; +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectManageFeign.java b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectManageFeign.java new file mode 100644 index 00000000..fe150014 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectManageFeign.java @@ -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 query(@RequestBody TaskQueryCriteria taskQueryCriteria); + +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectManageFeignFallBack.java b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectManageFeignFallBack.java new file mode 100644 index 00000000..913d909a --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectManageFeignFallBack.java @@ -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 query(TaskQueryCriteria taskQueryCriteria) { + return null; + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectSourceFeign.java b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectSourceFeign.java new file mode 100644 index 00000000..9369fc28 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectSourceFeign.java @@ -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 queryMemberNum(@RequestParam("memberId") Long memberId); +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectSourceFeignFallBack.java b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectSourceFeignFallBack.java new file mode 100644 index 00000000..8d2df4c4 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/feign/ConnectSourceFeignFallBack.java @@ -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 queryMemberNum(Long memberId) { + return null; + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/job/StatisticsHourJob.java b/manage/ad-platform-task/src/main/java/com/baiye/job/StatisticsHourJob.java new file mode 100644 index 00000000..2bcb01bf --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/job/StatisticsHourJob.java @@ -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(); + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/listener/JobListener.java b/manage/ad-platform-task/src/main/java/com/baiye/listener/JobListener.java new file mode 100644 index 00000000..673faf19 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/listener/JobListener.java @@ -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()); + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/service/ElasticJobService.java b/manage/ad-platform-task/src/main/java/com/baiye/service/ElasticJobService.java new file mode 100644 index 00000000..3433c7bc --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/service/ElasticJobService.java @@ -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 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); +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/service/ReportService.java b/manage/ad-platform-task/src/main/java/com/baiye/service/ReportService.java new file mode 100644 index 00000000..da8f9764 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/service/ReportService.java @@ -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); +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/service/impl/ElasticJobServiceImpl.java b/manage/ad-platform-task/src/main/java/com/baiye/service/impl/ElasticJobServiceImpl.java new file mode 100644 index 00000000..b57b674c --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/service/impl/ElasticJobServiceImpl.java @@ -0,0 +1,236 @@ +package com.baiye.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baiye.entity.Job; +import com.baiye.entity.JobBriefInfo; +import com.baiye.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; +import com.dangdang.ddframe.job.lite.api.JobScheduler; +import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration; +import com.dangdang.ddframe.job.lite.internal.config.LiteJobConfigurationGsonFactory; +import com.dangdang.ddframe.job.lite.internal.storage.JobNodePath; +import com.dangdang.ddframe.job.reg.base.CoordinatorRegistryCenter; +import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import lombok.extern.slf4j.Slf4j; +import org.apache.curator.framework.CuratorFramework; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; + +/** + * @author wjt + * @date 2021/11/26 + */ +@Slf4j +@Service +public class ElasticJobServiceImpl implements ElasticJobService { + @Resource + private CoordinatorRegistryCenter center; + @Resource + private ZookeeperRegistryCenter zookeeperRegistryCenter; +// @Resource +// private DataSource dataSource; + + @Override + public void addJob(Job job) { + boolean overwrite = job.getOverwrite(); + String exceptionClass = job.getJobProperties().get("JOB_EXCEPTION_HANDLER"); + if (StrUtil.isEmpty(exceptionClass)) { + exceptionClass = "com.baiye.exception.ElasticException"; + } + JobCoreConfiguration jcc = JobCoreConfiguration + .newBuilder(job.getJobName(), job.getCron(), job.getShardingTotalCount()) + .shardingItemParameters(job.getShardingItemParameters()) + .description(job.getDescription()) + .failover(job.isFailover()) + .jobParameter(job.getJobParameter()) + .misfire(job.isMisfire()) + .jobProperties(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), exceptionClass) + .jobProperties(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER.getKey(), job.getJobProperties().get("EXECUTOR_SERVICE_HANDLER")) + .build(); + SimpleJobConfiguration sjc = new SimpleJobConfiguration( + jcc, job.getJobClass() + ); + LiteJobConfiguration ljc = LiteJobConfiguration + .newBuilder(sjc) + .overwrite(overwrite) + .monitorPort(job.getMonitorPort()) + .monitorExecution(job.isMonitorExecution()) + .maxTimeDiffSeconds(job.getMaxTimeDiffSeconds()) + .jobShardingStrategyClass(job.getJobShardingStrategyClass()) + .reconcileIntervalMinutes(job.getReconcileIntervalMinutes()) + .build(); + // 配置数据源 +// JobEventConfiguration jec = new JobEventRdbConfiguration(dataSource); + //配置监听 +// MyNormalListener myNormalListener = new MyNormalListener(); + new JobScheduler(center, ljc).init(); + } + + @Override + public void removeJob(String jobName) { + try { + CuratorFramework client = zookeeperRegistryCenter.getClient(); + client.delete().deletingChildrenIfNeeded().forPath("/" + jobName); + } catch (Exception e) { + log.error("删除任务:{} 错误 {}", jobName, e.getMessage()); + } + } + + /** + * 获取任务的详情 + */ + @Override + public Job getJobDetail(String jobName) { + Job job = new Job(); + try { + JobNodePath jobNodePath = new JobNodePath(jobName); + LiteJobConfiguration liteJobConfig = LiteJobConfigurationGsonFactory.fromJson(center.get(jobNodePath.getConfigNodePath())); + job.setJobType(liteJobConfig.getTypeConfig().getJobType().name()); + this.buildSimpleJobSettings(jobName, job, liteJobConfig); + } catch (Exception e) { + log.error("查询job任务:{} 错误 {}", jobName, e.getMessage()); + return null; + } + return job; + } + + /** + * 获取所有任务的基本信息 + */ + @Override + public List getAllJobsDetails() { + List jobNames = zookeeperRegistryCenter.getChildrenKeys("/"); + List result = new ArrayList<>(jobNames.size()); + + for (String each : jobNames) { + JobBriefInfo jobBriefInfo = this.getJobBriefInfo(each); + if (null != jobBriefInfo) { + result.add(jobBriefInfo); + } + } + Collections.sort(result); + return result; + } + + @Override + public void updateJob(Job job) { + Preconditions.checkArgument(!Strings.isNullOrEmpty(job.getJobName()), "jobName can not be empty."); + Preconditions.checkArgument(!Strings.isNullOrEmpty(job.getCron()), "cron can not be empty."); + Preconditions.checkArgument(job.getShardingTotalCount() > 0, "shardingTotalCount should larger than zero."); + JobNodePath jobNodePath = new JobNodePath(job.getJobName()); + center.update(jobNodePath.getConfigNodePath(), LiteJobConfigurationGsonFactory.toJsonForObject(job)); + } + + + @Override + public void trigger(String jobName) { + JobNodePath jobNodePath = new JobNodePath(jobName); + for (String each : center.getChildrenKeys(jobNodePath.getInstancesNodePath())) { + center.persist(jobNodePath.getInstanceNodePath(each), "TRIGGER"); + } + } + + @Override + public void disable(String jobName) { + JobNodePath jobNodePath = new JobNodePath(jobName); + for (String each : center.getChildrenKeys(jobNodePath.getServerNodePath())) { + center.persist(jobNodePath.getServerNodePath(each), "DISABLED"); + } + } + + @Override + public void enable(String jobName) { + JobNodePath jobNodePath = new JobNodePath(jobName); + for (String each : center.getChildrenKeys(jobNodePath.getServerNodePath())) { + center.persist(jobNodePath.getServerNodePath(each), ""); + } + } + + @Override + public void shutdown(String jobName) { + JobNodePath jobNodePath = new JobNodePath(jobName); + for (String job : center.getChildrenKeys(jobNodePath.getInstancesNodePath())) { + center.remove(jobNodePath.getInstanceNodePath(job)); + } + } + + private void buildSimpleJobSettings(String jobName, Job job, LiteJobConfiguration liteJobConfig) { + job.setJobName(jobName); + job.setJobType(liteJobConfig.getTypeConfig().getJobType().name()); + job.setJobClass(liteJobConfig.getTypeConfig().getJobClass()); + job.setShardingTotalCount(liteJobConfig.getTypeConfig().getCoreConfig().getShardingTotalCount()); + job.setCron(liteJobConfig.getTypeConfig().getCoreConfig().getCron()); + job.setShardingItemParameters(liteJobConfig.getTypeConfig().getCoreConfig().getShardingItemParameters()); + job.setJobParameter(liteJobConfig.getTypeConfig().getCoreConfig().getJobParameter()); + job.setMonitorExecution(liteJobConfig.isMonitorExecution()); + job.setMaxTimeDiffSeconds(liteJobConfig.getMaxTimeDiffSeconds()); + job.setMonitorPort(liteJobConfig.getMonitorPort()); + job.setFailover(liteJobConfig.getTypeConfig().getCoreConfig().isFailover()); + job.setMisfire(liteJobConfig.getTypeConfig().getCoreConfig().isMisfire()); + job.setJobShardingStrategyClass(liteJobConfig.getJobShardingStrategyClass()); + job.setDescription(liteJobConfig.getTypeConfig().getCoreConfig().getDescription()); + job.setReconcileIntervalMinutes(liteJobConfig.getReconcileIntervalMinutes()); + job.setOverwrite(liteJobConfig.isOverwrite()); + } + + private JobBriefInfo getJobBriefInfo(String jobName) { + JobNodePath jobNodePath = new JobNodePath(jobName); + JobBriefInfo result = new JobBriefInfo(); + result.setJobName(jobName); + String liteJobConfigJson = center.get(jobNodePath.getConfigNodePath()); + if (null == liteJobConfigJson) { + return null; + } else { + LiteJobConfiguration liteJobConfig = LiteJobConfigurationGsonFactory.fromJson(liteJobConfigJson); + result.setDescription(liteJobConfig.getTypeConfig().getCoreConfig().getDescription()); + result.setCron(liteJobConfig.getTypeConfig().getCoreConfig().getCron()); + result.setInstanceCount(center.getChildrenKeys((new JobNodePath(jobName)).getInstancesNodePath()).size()); + result.setShardingTotalCount(liteJobConfig.getTypeConfig().getCoreConfig().getShardingTotalCount()); + result.setStatus(this.getJobStatus(jobName)); + return result; + } + } + + private JobBriefInfo.JobStatus getJobStatus(String jobName) { + JobNodePath jobNodePath = new JobNodePath(jobName); + List instances = center.getChildrenKeys(jobNodePath.getInstancesNodePath()); + if (instances.isEmpty()) { + return JobBriefInfo.JobStatus.CRASHED; + } else if (this.isAllDisabled(jobNodePath)) { + return JobBriefInfo.JobStatus.DISABLED; + } else { + return this.isHasShardingFlag(jobNodePath, instances) ? JobBriefInfo.JobStatus.SHARDING_FLAG : JobBriefInfo.JobStatus.OK; + } + } + + private boolean isAllDisabled(JobNodePath jobNodePath) { + List serversPath = zookeeperRegistryCenter.getChildrenKeys(jobNodePath.getServerNodePath()); + int disabledServerCount = 0; + for (String each : serversPath) { + if (JobBriefInfo.JobStatus.DISABLED.name().equals(center.get(jobNodePath.getServerNodePath(each)))) { + ++disabledServerCount; + } + } + + return disabledServerCount == serversPath.size(); + } + + private boolean isHasShardingFlag(JobNodePath jobNodePath, List instances) { + Set shardingInstances = new HashSet<>(); + for (String each : center.getChildrenKeys(jobNodePath.getShardingNodePath())) { + String instanceId = center.get(jobNodePath.getShardingNodePath(each, "instance")); + if (null != instanceId && !instanceId.isEmpty()) { + shardingInstances.add(instanceId); + } + } + + return !instances.containsAll(shardingInstances) || shardingInstances.isEmpty(); + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/service/impl/ReportServiceImpl.java b/manage/ad-platform-task/src/main/java/com/baiye/service/impl/ReportServiceImpl.java new file mode 100644 index 00000000..1b0af67e --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/service/impl/ReportServiceImpl.java @@ -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 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 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 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 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 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 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; + } +} diff --git a/manage/ad-platform-task/src/main/java/com/baiye/socket/WebSocketServer.java b/manage/ad-platform-task/src/main/java/com/baiye/socket/WebSocketServer.java new file mode 100644 index 00000000..da27f5d4 --- /dev/null +++ b/manage/ad-platform-task/src/main/java/com/baiye/socket/WebSocketServer.java @@ -0,0 +1,155 @@ +package com.baiye.socket; + +import cn.hutool.json.JSONUtil; +import com.baiye.entity.vo.ReportMessageInfoVO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author wjt + * @date 2021/12/13 + */ +@Slf4j +@Component +@ServerEndpoint(value = "/task/prosperous/{userId}") +public class WebSocketServer { + private static String user; + + @PostConstruct + public void init() { + log.info("websocket 加载"); + } + + private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0); + /** + * concurrent包的线程安全Set,用来存放每个客户端对应的Session对象。 + */ +// private static final CopyOnWriteArraySet SESSIONS = new CopyOnWriteArraySet<>(); + + private static ConcurrentHashMap SESSIONS = new ConcurrentHashMap(); + + /** + * 连接建立成功调用的方法 + */ + @OnOpen + public void onOpen(@PathParam(value = "userId") String userId, Session session) { + SESSIONS.put(userId, session); + user = userId; + // 在线数加1 + int cnt = ONLINE_COUNT.incrementAndGet(); + log.info("有连接加入,当前连接用户为 {},当前连接数为:{}", userId, cnt); + sendMessage(session, "连接成功"); + } + + /** + * 连接关闭调用的方法 + */ + @OnClose + public void onClose(Session session) { + if (user != null) { + SESSIONS.remove(user); + int cnt = ONLINE_COUNT.decrementAndGet(); + log.info("有连接关闭,当前连接数为:{}", cnt); + } + } + + /** + * 收到客户端消息后调用的方法 + * + * @param message 客户端发送过来的消息 + */ + @OnMessage + public void onMessage(String message, Session session) { + log.info("来自客户端的消息:{}", message); + sendMessage(session, "收到消息,消息内容:" + message); + + } + + /** + * 出现错误 + * + * @param session + * @param error + */ + @OnError + public void onError(Session session, Throwable error) { + log.error("发生错误:{},Session ID: {}", error.getMessage(), session.getId()); + error.printStackTrace(); + } + + /** + * 发送消息,实践表明,每次浏览器刷新,session会发生变化。 + * + * @param session + * @param message + */ + public static void sendMessage(Session session, String message) { + try { + session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s ,userId =%s)", message, session, user)); + } catch (IOException e) { + log.error("发送消息出错:{}", e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 群发消息 + * + * @param message + * @throws IOException + */ + public static void broadCastInfo(String message) { + for (String key : SESSIONS.keySet()) { + if (!user.equals(key)) { + sendMessage(SESSIONS.get(key), message); + } + } + } + + /** + * 指定Session发送消息 + * + * @param message + * @param sessionId + * @throws IOException + */ + public static void sendMessage(String message, String sessionId) throws IOException { + Session session = null; + if (SESSIONS.get(sessionId) != null) { + session = SESSIONS.get(sessionId); + } + if (session != null) { + sendMessage(session, message); + } else { + log.warn("没有找到你指定ID的会话:{}", sessionId); + } + } + + + public void sendMessage(ReportMessageInfoVO reportMessageInfoVO) throws IOException { + log.info("发给webSocket信息 {}", reportMessageInfoVO); + Session session = null; + for (String key : SESSIONS.keySet()) { + if (key.equals(String.valueOf(reportMessageInfoVO.getSessionId()))) { + session = SESSIONS.get(key); + break; + } + } + + if (session != null) { + session.getBasicRemote().sendText(JSONUtil.toJsonStr(reportMessageInfoVO)); + } else { + log.warn("没有找到你指定ID的会话:{}", reportMessageInfoVO.getSessionId()); + } + } + +} diff --git a/manage/ad-platform-task/src/main/resources/META-INF/spring-configuration-metadata.json b/manage/ad-platform-task/src/main/resources/META-INF/spring-configuration-metadata.json new file mode 100644 index 00000000..147a3aad --- /dev/null +++ b/manage/ad-platform-task/src/main/resources/META-INF/spring-configuration-metadata.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 + } + ] +} \ No newline at end of file diff --git a/manage/ad-platform-task/src/main/resources/application-dev.yml b/manage/ad-platform-task/src/main/resources/application-dev.yml new file mode 100644 index 00000000..49b27f95 --- /dev/null +++ b/manage/ad-platform-task/src/main/resources/application-dev.yml @@ -0,0 +1,133 @@ + +#配置数据源 +spring: + jpa: + show-sql: true + cloud: + nacos: + discovery: + server-addr: ${NACOS_HOST:118.178.137.129}:${NACOS_PORT:8848} + redis: + database: 2 + host: 118.178.137.129 + timeout: 5000 + datasource: + druid: + db-type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://118.178.137.129:3306/ad-platform?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull + username: root + password: root +# url: jdbc:mysql://localhost:3306/ad-platform?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull +# username: root +# password: 12345678 + # 初始连接数 + initial-size: 5 + # 最小连接数 + min-idle: 15 + # 最大连接数 + max-active: 30 + # 超时时间(以秒数为单位) + remove-abandoned-timeout: 180 + # 获取连接超时时间 + max-wait: 3000 + # 连接有效性检测时间 + time-between-eviction-runs-millis: 60000 + # 连接在池中最小生存的时间 + min-evictable-idle-time-millis: 300000 + # 连接在池中最大生存的时间 + max-evictable-idle-time-millis: 900000 + # 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除 + test-while-idle: true + # 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个 + test-on-borrow: true + # 是否在归还到池中前进行检验 + test-on-return: false + # 检测连接是否有效 + validation-query: select 1 + # 配置监控统计 + webStatFilter: + enabled: true + stat-view-servlet: + enabled: true + url-pattern: /druid/* + reset-enable: false + filter: + stat: + enabled: true + # 记录慢SQL + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + +# 登录相关配置 +login: + # 登录缓存 + cache-enable: true + # 是否限制单用户登录 + single-login: false + # 验证码 + login-code: + # 验证码类型配置 查看 LoginProperties 类 + code-type: arithmetic + # 登录图形验证码有效时间/分钟 + expiration: 2 + # 验证码高度 + width: 111 + # 验证码宽度 + height: 36 + # 内容长度 + length: 2 + # 字体名称,为空则使用默认字体 + font-name: + # 字体大小 + font-size: 25 + +#jwt +jwt: + header: Authorization + # 令牌前缀 + token-start-with: Bearer + # 必须使用最少88位的Base64对该令牌进行编码 + base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI= + # 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html + token-validity-in-seconds: 14400000 + # 在线用户key + online-key: online-token- + # 验证码 + code-key: code-key- + # token 续期检查时间范围(默认30分钟,单位毫秒),在token即将过期的一段时间内用户操作了,则给用户的token续期 + detect: 1800000 + # 续期时间范围,默认1小时,单位毫秒 + renew: 3600000 + +#是否允许生成代码,生产环境设置为false +generator: + enabled: true + +#是否开启 swagger-ui +swagger: + enabled: true + +# IP 本地解析 +ip: + local-parsing: true + +# 文件存储路径 +file: + mac: + path: ~/file/ + avatar: ~/avatar/ + linux: + path: /home/eladmin/file/ + avatar: /home/eladmin/avatar/ + windows: + path: C:\eladmin\file\ + avatar: C:\eladmin\avatar\ + # 文件大小 /M + maxSize: 100 + avatarMaxSize: 5 + diff --git a/manage/ad-platform-task/src/main/resources/application-prod.yml b/manage/ad-platform-task/src/main/resources/application-prod.yml new file mode 100644 index 00000000..e69de29b diff --git a/manage/ad-platform-task/src/main/resources/application-test.yml b/manage/ad-platform-task/src/main/resources/application-test.yml new file mode 100644 index 00000000..e69de29b diff --git a/manage/ad-platform-task/src/main/resources/application.yml b/manage/ad-platform-task/src/main/resources/application.yml new file mode 100644 index 00000000..db686217 --- /dev/null +++ b/manage/ad-platform-task/src/main/resources/application.yml @@ -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 \ No newline at end of file diff --git a/manage/ad-platform-task/src/main/resources/logback-spring.xml b/manage/ad-platform-task/src/main/resources/logback-spring.xml new file mode 100644 index 00000000..9a2d33d3 --- /dev/null +++ b/manage/ad-platform-task/src/main/resources/logback-spring.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + + + + + + ${log.path}/debug.log + + ${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz + 50MB + 30 + + + %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n + + + + + + ${log.path}/error.log + + ${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz + 50MB + 30 + + + %date [%thread] %-5level [%logger{50}] %file:%line - %msg%n + + + ERROR + + + + + + + + + + + + + + +