feat(3.2.0):工作流Dasharboard提交

完成工作流Dasharboard
This commit is contained in:
wodeyangzipingpingwuqi 2024-03-26 02:54:01 +00:00 committed by byteblogs168
parent 1a9d2e43bc
commit ad5dd3db1c
20 changed files with 631 additions and 72 deletions

View File

@ -29,6 +29,11 @@ public class JobBatchSummaryResponseDO {
*/
private Long jobId;
/**
* 工作流任务id
*/
//private Long workflowId;
/**
* 任务批次状态
*/

View File

@ -25,19 +25,23 @@ public interface JobSummaryMapper extends BaseMapper<JobSummary> {
IPage<DashboardRetryLineResponseDO.Task> jobTaskList(@Param("namespaceId") String namespaceId, @Param("groupNames") List<String> groupNames, Page<Object> page);
List<DashboardLineResponseDO> jobLineList(@Param("namespaceId") String namespaceId,
List<DashboardLineResponseDO> jobLineList(
@Param("systemTaskType") Integer systemTaskType,
@Param("namespaceId") String namespaceId,
@Param("groupNames") List<String> groupNames,
@Param("groupName") String groupName,
@Param("type") String type,
@Param("dateFormat") String dateFormat,
@Param("from") LocalDateTime from,
@Param("to") LocalDateTime to);
DashboardCardResponseDO.JobTask toJobTask(@Param("namespaceId") String namespaceId, @Param("groupNames") List<String> groupNames);
List<DashboardRetryLineResponseDO.Rank> dashboardRank(@Param("namespaceId") String namespaceId,
List<DashboardRetryLineResponseDO.Rank> dashboardRank(
@Param("systemTaskType") Integer systemTaskType,
@Param("namespaceId") String namespaceId,
@Param("groupNames") List<String> groupNames,
@Param("groupName") String groupName,
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime
);
DashboardCardResponseDO.JobTask toJobTask(@Param("systemTaskType") Integer systemTaskType, @Param("namespaceId") String namespaceId, @Param("groupNames") List<String> groupNames);
}

View File

@ -27,5 +27,7 @@ public interface JobTaskBatchMapper extends BaseMapper<JobTaskBatch> {
List<JobBatchResponseDO> selectJobBatchListByIds(@Param("ids") List<Long> ids);
List<JobBatchSummaryResponseDO> summaryJobBatchList(@Param("from") LocalDateTime todayFrom, @Param("to") LocalDateTime to);
List<JobBatchSummaryResponseDO> summaryJobBatchList(@Param("systemTaskType") Integer systemTaskType, @Param("from") LocalDateTime todayFrom, @Param("to") LocalDateTime to);
List<JobBatchSummaryResponseDO> summaryWorkflowTaskBatchList(@Param("from") LocalDateTime todayFrom, @Param("to") LocalDateTime to);
}

View File

@ -92,4 +92,8 @@ public class JobSummary implements Serializable {
*/
private LocalDateTime updateDt;
/**
* 任务类型 3JOB任务 4WORKFLOW任务
*/
private Integer systemTaskType;
}

View File

@ -20,7 +20,7 @@
<insert id="insertOrUpdate" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
INSERT INTO
job_summary (namespace_id, group_name, job_id, trigger_at,
job_summary (namespace_id, group_name, job_id, trigger_at, system_task_type,
success_num,fail_num,fail_reason,stop_num,stop_reason, cancel_num,cancel_reason)
VALUES
<foreach collection="list" item="item" separator=",">
@ -29,6 +29,7 @@
#{item.groupName},
#{item.jobId},
#{item.triggerAt},
#{item.systemTaskType},
#{item.successNum},
#{item.failNum},
#{item.failReason},
@ -51,24 +52,7 @@
<select id="jobLineList"
resultType="com.aizuda.easy.retry.template.datasource.persistence.dataobject.DashboardLineResponseDO">
SELECT
<choose>
<when test="type == 'DAY'">
DATE_FORMAT(create_dt,'%H')
</when>
<when test="type == 'WEEK'">
DATE_FORMAT(create_dt,'%Y-%m-%d')
</when>
<when test="type =='MONTH'">
DATE_FORMAT(create_dt,'%Y-%m-%d')
</when>
<when test="type == 'YEAR'">
DATE_FORMAT(create_dt,'%Y-%m')
</when>
<otherwise>
DATE_FORMAT(create_dt,'%Y-%m-%d')
</otherwise>
</choose>
AS createDt,
DATE_FORMAT(trigger_at, #{dateFormat}) AS createDt,
ifnull(SUM(success_num), 0) AS success,
ifnull(SUM(stop_num), 0) AS stop,
ifnull(SUM(cancel_num), 0) AS cancel,
@ -85,20 +69,21 @@
<if test="groupName != null and groupName != '' ">
AND group_name = #{groupName}
</if>
AND namespace_id = #{namespaceId} AND trigger_at BETWEEN #{from} AND #{to}
AND system_task_type = #{systemTaskType} AND namespace_id = #{namespaceId} AND trigger_at BETWEEN #{from} AND #{to}
</where>
GROUP BY createDt
GROUP BY DATE_FORMAT(trigger_at, #{dateFormat})
</select>
<select id="toJobTask"
resultType="com.aizuda.easy.retry.template.datasource.persistence.dataobject.DashboardCardResponseDO$JobTask">
SELECT ifnull(sum(success_num), 0) AS successNum,
SELECT
ifnull(sum(success_num), 0) AS successNum,
ifnull(sum(stop_num), 0) AS stopNum,
ifnull(sum(cancel_num), 0) AS cancelNum,
ifnull(sum(fail_num), 0) AS failNum,
ifnull(sum(success_num + fail_num + stop_num + cancel_num), 0) AS totalNum
FROM job_summary
WHERE namespace_id = #{namespaceId}
WHERE system_task_type = #{systemTaskType} AND namespace_id = #{namespaceId}
<if test="groupNames != null and groupNames.size > 0">
AND group_name IN
<foreach collection="groupNames" item="groupName" open="(" separator="," close=")">
@ -110,7 +95,12 @@
<select id="dashboardRank"
resultType="com.aizuda.easy.retry.template.datasource.persistence.dataobject.DashboardRetryLineResponseDO$Rank">
SELECT
<if test="systemTaskType == 3">
CONCAT(group_name, '/', (SELECT job_name FROM job WHERE id = job_id)) `name`,
</if>
<if test="systemTaskType == 4">
CONCAT(group_name, '/', (SELECT workflow_name FROM workflow WHERE id = job_id)) `name`,
</if>
SUM(fail_num) AS total FROM job_summary
<where>
<if test="groupNames != null and groupNames.size > 0">
@ -124,6 +114,7 @@
</if>
AND trigger_at >= #{startTime} AND trigger_at &lt;= #{endTime}
</where>
AND system_task_type = #{systemTaskType}
AND namespace_id = #{namespaceId}
GROUP BY namespace_id, group_name, job_id
HAVING total > 0

View File

@ -55,9 +55,25 @@
SUM(CASE WHEN (task_batch_status = 5) THEN 1 ELSE 0 END) AS stopNum,
SUM(CASE WHEN (task_batch_status = 4) THEN 1 ELSE 0 END) AS failNum
FROM job_task_batch
WHERE create_dt BETWEEN #{from} AND #{to}
WHERE system_task_type = #{systemTaskType} AND create_dt BETWEEN #{from} AND #{to}
GROUP BY namespace_id, group_name, job_id, task_batch_status, operation_reason
</select>
<select id="summaryWorkflowTaskBatchList"
resultType="com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchSummaryResponseDO">
SELECT namespace_id AS namespaceId,
workflow_id AS jobId,
group_name AS groupName,
task_batch_status AS taskBatchStatus,
operation_reason AS operationReason,
COUNT(operation_reason) AS operationReasonTotal,
SUM(CASE WHEN (task_batch_status = 3) THEN 1 ELSE 0 END) AS successNum,
SUM(CASE WHEN (task_batch_status = 6) THEN 1 ELSE 0 END) AS cancelNum,
SUM(CASE WHEN (task_batch_status = 5) THEN 1 ELSE 0 END) AS stopNum,
SUM(CASE WHEN (task_batch_status = 4) THEN 1 ELSE 0 END) AS failNum
FROM workflow_task_batch
WHERE create_dt BETWEEN #{from} AND #{to}
GROUP BY namespace_id, group_name, workflow_id, task_batch_status, operation_reason
</select>
<select id="selectJobBatchListByIds"

View File

@ -0,0 +1,35 @@
package com.aizuda.easy.retry.server.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
*
* @author zhengweilin
* @version 1.0.0
* @date 2024/03/26
*/
@AllArgsConstructor
@Getter
public enum DashboardLineEnum {
DAY("DAY", "%H"),
WEEK("WEEK", "%Y-%m-%d"),
MONTH("MONTH", "%Y-%m-%d"),
YEAR("YEAR", "%Y-%m"),
;
private final String unit;
private final String dateFormat;
public static DashboardLineEnum modeOf(String mode) {
for (DashboardLineEnum value : DashboardLineEnum.values()) {
if (value.getUnit().equals(mode)) {
return value;
}
}
return DashboardLineEnum.WEEK;
}
}

View File

@ -6,6 +6,7 @@ import com.aizuda.easy.retry.common.core.util.JsonUtil;
import com.aizuda.easy.retry.server.common.Lifecycle;
import com.aizuda.easy.retry.server.common.config.SystemProperties;
import com.aizuda.easy.retry.server.common.dto.JobTaskBatchReason;
import com.aizuda.easy.retry.server.common.enums.SyetemTaskTypeEnum;
import com.aizuda.easy.retry.server.common.schedule.AbstractSchedule;
import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchSummaryResponseDO;
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobSummaryMapper;
@ -62,7 +63,7 @@ public class JobSummarySchedule extends AbstractSchedule implements Lifecycle {
// 定时按日实时查询统计数据00:00:00 - 23:59:59
LocalDateTime todayFrom = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).plusDays(-i);
LocalDateTime todayTo = LocalDateTime.of(LocalDate.now(), LocalTime.MAX).plusDays(-i);
List<JobBatchSummaryResponseDO> summaryResponseDOList = jobTaskBatchMapper.summaryJobBatchList(todayFrom, todayTo);
List<JobBatchSummaryResponseDO> summaryResponseDOList = jobTaskBatchMapper.summaryJobBatchList(SyetemTaskTypeEnum.JOB.getType(), todayFrom, todayTo);
if (summaryResponseDOList == null || summaryResponseDOList.size() < 1) {
continue;
}
@ -86,6 +87,7 @@ public class JobSummarySchedule extends AbstractSchedule implements Lifecycle {
jobSummary.setTriggerAt(triggerAt);
jobSummary.setNamespaceId(job.getValue().get(0).getNamespaceId());
jobSummary.setGroupName(job.getValue().get(0).getGroupName());
jobSummary.setSystemTaskType(SyetemTaskTypeEnum.JOB.getType());
jobSummary.setSuccessNum(job.getValue().stream().mapToInt(JobBatchSummaryResponseDO::getSuccessNum).sum());
jobSummary.setFailNum(job.getValue().stream().mapToInt(JobBatchSummaryResponseDO::getFailNum).sum());
jobSummary.setStopNum(job.getValue().stream().mapToInt(JobBatchSummaryResponseDO::getStopNum).sum());

View File

@ -0,0 +1,135 @@
package com.aizuda.easy.retry.server.job.task.support.schedule;
import com.aizuda.easy.retry.common.core.enums.JobTaskBatchStatusEnum;
import com.aizuda.easy.retry.common.core.util.JsonUtil;
import com.aizuda.easy.retry.common.log.EasyRetryLog;
import com.aizuda.easy.retry.server.common.Lifecycle;
import com.aizuda.easy.retry.server.common.config.SystemProperties;
import com.aizuda.easy.retry.server.common.dto.JobTaskBatchReason;
import com.aizuda.easy.retry.server.common.enums.SyetemTaskTypeEnum;
import com.aizuda.easy.retry.server.common.schedule.AbstractSchedule;
import com.aizuda.easy.retry.template.datasource.persistence.dataobject.JobBatchSummaryResponseDO;
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobSummaryMapper;
import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobTaskBatchMapper;
import com.aizuda.easy.retry.template.datasource.persistence.po.JobSummary;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Job Dashboard
*
* @author: wodeyangzipingpingwuqi
* @date : 2024-03-25 10:16
* @since 3.2.0
*/
@Component
@Slf4j
public class WorkflowJobSummarySchedule extends AbstractSchedule implements Lifecycle {
@Autowired
private JobTaskBatchMapper jobTaskBatchMapper;
@Autowired
private JobSummaryMapper jobSummaryMapper;
@Autowired
private SystemProperties systemProperties;
@Override
public String lockName() {
return "workflowJobSummarySchedule";
}
@Override
public String lockAtMost() {
return "PT1M";
}
@Override
public String lockAtLeast() {
return "PT20S";
}
@Override
protected void doExecute() {
try {
for (int i = 0; i < systemProperties.getSummaryDay(); i++) {
// 定时按日实时查询统计数据00:00:00 - 23:59:59
LocalDateTime todayFrom = LocalDateTime.of(LocalDate.now(), LocalTime.MIN).plusDays(-i);
LocalDateTime todayTo = LocalDateTime.of(LocalDate.now(), LocalTime.MAX).plusDays(-i);
List<JobBatchSummaryResponseDO> summaryWorkflowResponseDOList = jobTaskBatchMapper.summaryWorkflowTaskBatchList(todayFrom, todayTo);
if (summaryWorkflowResponseDOList == null || summaryWorkflowResponseDOList.size() < 1) {
continue;
}
// insertOrUpdate
List<JobSummary> jobSummaryList = jobSummaryList(todayFrom, summaryWorkflowResponseDOList);
int totalJobSummary = jobSummaryMapper.insertOrUpdate(jobSummaryList);
EasyRetryLog.LOCAL.debug("workflow job summary dashboard success todayFrom:[{}] todayTo:[{}] total:[{}]", todayFrom, todayTo, totalJobSummary);
}
} catch (Exception e) {
EasyRetryLog.LOCAL.error("workflow job summary dashboard log error", e);
}
}
private List<JobSummary> jobSummaryList(LocalDateTime triggerAt, List<JobBatchSummaryResponseDO> summaryResponseDOList) {
List<JobSummary> jobSummaryList = new ArrayList<>();
Map<Long, List<JobBatchSummaryResponseDO>> jobIdListMap = summaryResponseDOList.parallelStream().collect(Collectors.groupingBy(JobBatchSummaryResponseDO::getJobId));
for (Map.Entry<Long, List<JobBatchSummaryResponseDO>> job : jobIdListMap.entrySet()) {
JobSummary jobSummary = new JobSummary();
jobSummary.setJobId(job.getKey());
jobSummary.setTriggerAt(triggerAt);
jobSummary.setNamespaceId(job.getValue().get(0).getNamespaceId());
jobSummary.setGroupName(job.getValue().get(0).getGroupName());
jobSummary.setSystemTaskType(SyetemTaskTypeEnum.WORKFLOW.getType());
jobSummary.setSuccessNum(job.getValue().stream().mapToInt(JobBatchSummaryResponseDO::getSuccessNum).sum());
jobSummary.setFailNum(job.getValue().stream().mapToInt(JobBatchSummaryResponseDO::getFailNum).sum());
jobSummary.setStopNum(job.getValue().stream().mapToInt(JobBatchSummaryResponseDO::getStopNum).sum());
jobSummary.setCancelNum(job.getValue().stream().mapToInt(JobBatchSummaryResponseDO::getCancelNum).sum());
jobSummary.setFailReason(JsonUtil.toJsonString(jobTaskBatchReasonList(JobTaskBatchStatusEnum.FAIL.getStatus(), job.getValue())));
jobSummary.setStopReason(JsonUtil.toJsonString(jobTaskBatchReasonList(JobTaskBatchStatusEnum.STOP.getStatus(), job.getValue())));
jobSummary.setCancelReason(JsonUtil.toJsonString(jobTaskBatchReasonList(JobTaskBatchStatusEnum.CANCEL.getStatus(), job.getValue())));
jobSummaryList.add(jobSummary);
}
return jobSummaryList;
}
/**
* 批次状态查询 (操作原因 && 总数)
*
* @param jobTaskBatchStatus
* @param jobBatchSummaryResponseDOList
* @return
*/
private List<JobTaskBatchReason> jobTaskBatchReasonList(int jobTaskBatchStatus, List<JobBatchSummaryResponseDO> jobBatchSummaryResponseDOList) {
List<JobTaskBatchReason> jobTaskBatchReasonArrayList = new ArrayList<>();
List<JobBatchSummaryResponseDO> summaryResponseDOList = jobBatchSummaryResponseDOList.stream().filter(i -> jobTaskBatchStatus == i.getTaskBatchStatus()).collect(Collectors.toList());
for (JobBatchSummaryResponseDO jobBatchSummaryResponseDO : summaryResponseDOList) {
JobTaskBatchReason jobTaskBatchReason = new JobTaskBatchReason();
jobTaskBatchReason.setReason(jobBatchSummaryResponseDO.getOperationReason());
jobTaskBatchReason.setTotal(jobBatchSummaryResponseDO.getOperationReasonTotal());
jobTaskBatchReasonArrayList.add(jobTaskBatchReason);
}
return jobTaskBatchReasonArrayList;
}
@Override
public void start() {
taskScheduler.scheduleAtFixedRate(this::execute, Duration.parse("PT1H"));
}
@Override
public void close() {
}
}

View File

@ -51,12 +51,13 @@ public class DashBoardController {
@LoginRequired
@GetMapping("/job/line")
public DashboardRetryLineResponseVO jobLineList(BaseQueryVO baseQueryVO,
@RequestParam(value = "mode", required = false) String mode,
@RequestParam(value = "groupName", required = false) String groupName,
@RequestParam(value = "type", required = false, defaultValue = "WEEK") String type,
@RequestParam(value = "startTime", required = false) String startTime,
@RequestParam(value = "endTime", required = false) String endTime
) {
return dashBoardService.jobLineList(baseQueryVO, groupName, type, startTime, endTime);
return dashBoardService.jobLineList(baseQueryVO, mode, groupName, type, startTime, endTime);
}
@LoginRequired

View File

@ -18,6 +18,11 @@ public class DashboardCardResponseVO {
*/
private JobTask jobTask;
/**
* 工作流任务
*/
private WorkFlowTask workFlowTask;
/**
* 重试任务
*/
@ -77,6 +82,22 @@ public class DashboardCardResponseVO {
private BigDecimal successRate;
}
@Data
public static class WorkFlowTask {
//成功
private Integer successNum;
//失败
private Integer failNum;
//取消
private Integer cancelNum;
//停止
private Integer stopNum;
// 总数
private Integer totalNum;
// 成功率
private BigDecimal successRate;
}
@Data
@Accessors(chain = true)
public static class RetryTaskBar {

View File

@ -19,7 +19,7 @@ public interface DashBoardService {
DashboardRetryLineResponseVO retryLineList(BaseQueryVO baseQueryVO, String groupName, String type, String startTime, String endTime);
DashboardRetryLineResponseVO jobLineList(BaseQueryVO baseQueryVO, String groupName, String type, String startTime, String endTime);
DashboardRetryLineResponseVO jobLineList(BaseQueryVO baseQueryVO, String mode, String groupName, String type, String startTime, String endTime);
PageResult<List<ServerNodeResponseVO>> pods(ServerNodeQueryVO serverNodeQueryVO);
}

View File

@ -29,6 +29,11 @@ public interface JobSummaryResponseVOConverter {
})
DashboardCardResponseVO.JobTask toTaskJob(DashboardCardResponseDO.JobTask jobTask);
@Mappings({
@Mapping(target = "successRate", expression = "java(JobSummaryResponseVOConverter.toSuccessRate(jobTask.getSuccessNum(), jobTask.getTotalNum()))")
})
DashboardCardResponseVO.WorkFlowTask toWorkFlowTask(DashboardCardResponseDO.JobTask jobTask);
List<DashboardRetryLineResponseVO.Task> toDashboardRetryLineResponseVO(List<DashboardRetryLineResponseDO.Task> taskList);
static BigDecimal toSuccessRate(Integer successNum, Integer totalNum) {

View File

@ -9,6 +9,9 @@ import com.aizuda.easy.retry.common.log.EasyRetryLog;
import com.aizuda.easy.retry.server.common.config.SystemProperties;
import com.aizuda.easy.retry.server.common.dto.DistributeInstance;
import com.aizuda.easy.retry.server.common.dto.ServerNodeExtAttrs;
import com.aizuda.easy.retry.server.common.enums.DashboardLineEnum;
import com.aizuda.easy.retry.server.common.enums.SyetemTaskTypeEnum;
import com.aizuda.easy.retry.server.common.enums.SystemModeEnum;
import com.aizuda.easy.retry.server.common.register.ServerRegister;
import com.aizuda.easy.retry.server.web.model.base.BaseQueryVO;
import com.aizuda.easy.retry.server.web.model.base.PageResult;
@ -77,9 +80,17 @@ public class DashBoardServiceImpl implements DashBoardService {
List<String> groupNames = userSessionVO.isUser() ? userSessionVO.getGroupNames() : new ArrayList<>();
DashboardCardResponseVO dashboardCardResponseVO = new DashboardCardResponseVO();
// 重试任务
dashboardCardResponseVO.setRetryTask(RetrySummaryResponseVOConverter.INSTANCE.toRetryTask(retrySummaryMapper.retryTask(namespaceId, groupNames)));
DashboardCardResponseDO.RetryTask retryTaskDO = retrySummaryMapper.retryTask(namespaceId, groupNames);
DashboardCardResponseVO.RetryTask retryTaskVO = RetrySummaryResponseVOConverter.INSTANCE.toRetryTask(retryTaskDO);
dashboardCardResponseVO.setRetryTask(retryTaskVO);
// 定时任务
dashboardCardResponseVO.setJobTask(JobSummaryResponseVOConverter.INSTANCE.toTaskJob(jobSummaryMapper.toJobTask(namespaceId, groupNames)));
DashboardCardResponseDO.JobTask jobTaskDO = jobSummaryMapper.toJobTask(SyetemTaskTypeEnum.JOB.getType(), namespaceId, groupNames);
DashboardCardResponseVO.JobTask jobTaskVO = JobSummaryResponseVOConverter.INSTANCE.toTaskJob(jobTaskDO);
dashboardCardResponseVO.setJobTask(jobTaskVO);
// 工作流任务
DashboardCardResponseDO.JobTask workFlowTaskDO = jobSummaryMapper.toJobTask(SyetemTaskTypeEnum.WORKFLOW.getType(), namespaceId, groupNames);
DashboardCardResponseVO.WorkFlowTask workFlowTaskVO = JobSummaryResponseVOConverter.INSTANCE.toWorkFlowTask(workFlowTaskDO);
dashboardCardResponseVO.setWorkFlowTask(workFlowTaskVO);
// 重试任务柱状图
HashMap<LocalDateTime, DashboardCardResponseVO.RetryTaskBar> retryTaskBarMap = new HashMap<>();
for (int i = 0; i < 7; i++) {
@ -146,7 +157,7 @@ public class DashBoardServiceImpl implements DashBoardService {
}
@Override
public DashboardRetryLineResponseVO jobLineList(BaseQueryVO baseQueryVO, String groupName, String type, String startTime, String endTime) {
public DashboardRetryLineResponseVO jobLineList(BaseQueryVO baseQueryVO, String mode, String groupName, String type, String startTime, String endTime) {
// 查询登录用户权限
UserSessionVO userSessionVO = UserSessionUtils.currentUserSession();
@ -159,6 +170,8 @@ public class DashBoardServiceImpl implements DashBoardService {
if (DbTypeEnum.SQLSERVER.equals(systemProperties.getDbType())) {
pager.setCountId("sqlServer_jobTaskList_Count");
}
// 任务类型
Integer systemTaskType = SystemModeEnum.JOB.name().equals(mode) ? SyetemTaskTypeEnum.JOB.getType() : SyetemTaskTypeEnum.WORKFLOW.getType();
IPage<DashboardRetryLineResponseDO.Task> IPage = jobSummaryMapper.jobTaskList(namespaceId, groupNames, pager);
List<DashboardRetryLineResponseVO.Task> taskList = JobSummaryResponseVOConverter.INSTANCE.toDashboardRetryLineResponseVO(IPage.getRecords());
PageResult<List<DashboardRetryLineResponseVO.Task>> pageResult = new PageResult<>(new PageDTO(IPage.getCurrent(), IPage.getSize(), IPage.getTotal()), taskList);
@ -168,14 +181,14 @@ public class DashBoardServiceImpl implements DashBoardService {
DateTypeEnum dateTypeEnum = DateTypeEnum.valueOf(type);
LocalDateTime startDateTime = dateTypeEnum.getStartTime().apply(StrUtil.isNotBlank(startTime) ? LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
LocalDateTime endDateTime = dateTypeEnum.getEndTime().apply(StrUtil.isNotBlank(endTime) ? LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
List<DashboardLineResponseDO> dashboardLineResponseDOList = jobSummaryMapper.jobLineList(namespaceId, groupNames, groupName, type, startDateTime, endDateTime);
List<DashboardLineResponseDO> dashboardLineResponseDOList = jobSummaryMapper.jobLineList(systemTaskType, namespaceId, groupNames, groupName, DashboardLineEnum.modeOf(type).getDateFormat(), startDateTime, endDateTime);
List<DashboardLineResponseVO> dashboardLineResponseVOList = DispatchQuantityResponseVOConverter.INSTANCE.toDashboardLineResponseVO(dashboardLineResponseDOList);
dateTypeEnum.getConsumer().accept(dashboardLineResponseVOList);
dashboardLineResponseVOList.sort(Comparator.comparing(a -> a.getCreateDt()));
dashboardRetryLineResponseVO.setDashboardLineResponseDOList(dashboardLineResponseVOList);
// 排行榜
List<DashboardRetryLineResponseDO.Rank> rankList = jobSummaryMapper.dashboardRank(namespaceId, groupNames, groupName, startDateTime, endDateTime);
List<DashboardRetryLineResponseDO.Rank> rankList = jobSummaryMapper.dashboardRank(systemTaskType, namespaceId, groupNames, groupName, startDateTime, endDateTime);
List<DashboardRetryLineResponseVO.Rank> ranks = SceneQuantityRankResponseVOConverter.INSTANCE.toDashboardRetryLineResponseVORank(rankList);
dashboardRetryLineResponseVO.setRankList(ranks);
return dashboardRetryLineResponseVO;

View File

@ -20,14 +20,15 @@ export default {
}
},
mounted () {
this.getDashboardJobLine()
this.getDashboardJobLine('JOB', '')
this.createView()
},
methods: {
getDashboardJobLine (groupName, type = 'WEEK', startTime, endTime) {
getDashboardJobLine (mode, groupName, type = 'WEEK', startTime, endTime) {
getDashboardJobLine({
'groupName': groupName,
'mode': mode,
'type': type,
'groupName': groupName,
'startTime': startTime,
'endTime': endTime
}).then(res => {

View File

@ -0,0 +1,88 @@
<template>
<div>
<div id="workFlowViewData"></div>
</div>
</template>
<script>
import * as G2 from '@antv/g2'
import { getDashboardJobLine } from '@/api/manage'
const DataSet = require('@antv/data-set')
export default {
name: 'WorkFlowLine',
data () {
return {
viewRecords: [],
dashboardLineResponseDOList: [],
chart: null
}
},
mounted () {
this.getDashboardJobLine('WORKFLOW', '')
this.createView()
},
methods: {
getDashboardJobLine (mode, groupName, type = 'WEEK', startTime, endTime) {
getDashboardJobLine({
'mode': mode,
'type': type,
'groupName': groupName,
'startTime': startTime,
'endTime': endTime
}).then(res => {
this.$bus.$emit('WORKFLOW', res)
this.viewCharts(res.data.dashboardLineResponseDOList)
})
},
viewCharts (viewRecords, type = 'WEEK') {
var ds = new DataSet()
if (viewRecords === undefined || viewRecords === null) {
return
}
var dv = ds.createView().source(viewRecords)
dv.transform({
type: 'fold',
fields: ['success', 'fail', 'stop', 'cancel'],
key: 'name',
value: 'viewTotal',
retains: ['total', 'createDt']
})
this.chart.source(dv, {
date: {
type: 'cat'
}
})
this.chart.axis('viewTotal', {
label: {
textStyle: {
fill: '#aaaaaa'
}
}
})
this.chart.tooltip({
crosshairs: {
type: 'line'
}
})
this.chart.line().position('createDt*viewTotal').color('name', ['#1890ff', '#c28c62']).shape('smooth')
this.chart.point().position('createDt*viewTotal').color('name', ['#1890ff', '#c28c62']).size(4).shape('circle').style({
stroke: '#fff',
lineWidth: 1
})
this.chart.render()
},
createView () {
this.chart = new G2.Chart({
container: 'workFlowViewData',
forceFit: true,
height: 410,
padding: [20, 90, 60, 50]
})
}
}
}
</script>

View File

@ -8,6 +8,7 @@ export default {
'dashboard.analysis.job_stop': '停止',
'dashboard.analysis.job_cancel': '取消',
'dashboard.analysis.visits': '定时任务',
'dashboard.analysis.work-flow-job': '工作流任务',
'dashboard.analysis.visits-trend': '访问量趋势',
'dashboard.analysis.visits-ranking': '门店访问量排名',
'dashboard.analysis.day-visits': '日访问量',

View File

@ -1,7 +1,7 @@
<template>
<div>
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="8" :style="{ marginBottom: '24px' }">
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" :title="$t('dashboard.analysis.total-sales')" :total="retryTask.totalNum">
<a-tooltip title="总任务量: 重试/回调任务量" slot="action">
<a-icon type="info-circle-o" />
@ -31,7 +31,7 @@
</template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="8" :style="{ marginBottom: '24px' }">
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="定时任务" :total="jobTask.totalNum">
<a-tooltip title="成功率:总完成/总调度量;" slot="action">
<a-icon type="info-circle-o" />
@ -56,7 +56,34 @@
</template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="8" :style="{ marginBottom: '24px' }">
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="工作流任务" :total="workFlowTask.totalNum"><!-- -->
<a-tooltip title="成功率:总完成/总调度量;" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<a-tooltip title="成功率">
<a-progress stroke-linecap="square" :percent="workFlowTask.successRate" />
</a-tooltip>
</div>
<template slot="footer">
{{ $t('dashboard.analysis.job_success') }}
<span>{{ workFlowTask.successNum }}</span>
<a-divider type="vertical" />
{{ $t('dashboard.analysis.job_fail') }}
<span>{{ workFlowTask.failNum }}</span>
<a-divider type="vertical" />
{{ $t('dashboard.analysis.job_stop') }}
<span>{{ workFlowTask.stopNum }}</span>
<a-divider type="vertical" />
{{ $t('dashboard.analysis.job_cancel') }}
<span>{{ workFlowTask.cancelNum }}</span>
</template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<a href="#" @click="jumpPosList">
<chart-card :loading="loading" title="总在线机器" :total="onLineService.total">
<a-tooltip title="总在线机器:注册到系统的客户端和服务端之和" slot="action" >
@ -103,6 +130,11 @@
<job-analysis ref="jobAnalysisRef"/>
</div>
</a-tab-pane>
<a-tab-pane :tab="$t('dashboard.analysis.work-flow-job')" key="WORKFLOW">
<div>
<work-flow-analysis ref="workFlowAnalysisRef"/>
</div>
</a-tab-pane>
</a-tabs>
</div>
</a-card>
@ -123,6 +155,7 @@ import {
import { getAllGroupNameList, getDashboardTaskRetryJob } from '@/api/manage'
import RetryAnalysis from '@/views/dashboard/RetryAnalysis.vue'
import JobAnalysis from '@/views/dashboard/JobAnalysis.vue'
import WorkFlowAnalysis from '@/views/dashboard/WorkFlowAnalysis.vue'
import { APP_MODE } from '@/store/mutation-types'
import storage from 'store'
import moment from 'moment'
@ -132,6 +165,7 @@ export default {
components: {
RetryAnalysis,
JobAnalysis,
WorkFlowAnalysis,
ChartCard,
MiniArea,
MiniProgress,
@ -163,6 +197,14 @@ export default {
stopNum: 0,
totalNum: 0
},
workFlowTask: {
successRate: 0,
successNum: 0,
failNum: 0,
cancelNum: 0,
stopNum: 0,
totalNum: 0
},
onLineService: {
clientTotal: 0,
serverTotal: 0,
@ -182,20 +224,39 @@ export default {
},
dataHandler (type) {
this.type = type
this.mode === 'ALL' || this.mode === 'RETRY' ? this.$refs.retryAnalysisRef.dataHandler(this.type) : this.$refs.jobAnalysisRef.dataHandler(this.type)
if (this.mode === 'ALL' || this.mode === 'RETRY') {
this.$refs.retryAnalysisRef.dataHandler(this.type)
} else if (this.mode === 'JOB') {
this.$refs.jobAnalysisRef.dataHandler(this.mode, this.type)
} else if (this.mode === 'WORKFLOW') {
this.$refs.workFlowAnalysisRef.dataHandler(this.mode, this.type)
}
},
dateChange (date, dateString) {
this.mode === 'ALL' || this.mode === 'RETRY' ? this.$refs.retryAnalysisRef.dateChange(date, dateString) : this.$refs.jobAnalysisRef.dateChange(date, dateString)
if (this.mode === 'ALL' || this.mode === 'RETRY') {
this.$refs.retryAnalysisRef.dateChange(date, dateString)
} else if (this.mode === 'JOB') {
this.$refs.jobAnalysisRef.dateChange(this.mode, date, dateString)
} else if (this.mode === 'WORKFLOW') {
this.$refs.workFlowAnalysisRef.dateChange(this.mode, date, dateString)
}
},
handleChange (value) {
this.mode === 'ALL' || this.mode === 'RETRY' ? this.$refs.retryAnalysisRef.handleChange(value) : this.$refs.jobAnalysisRef.handleChange(value)
if (this.mode === 'ALL' || this.mode === 'RETRY') {
this.$refs.retryAnalysisRef.handleChange(value)
} else if (this.mode === 'JOB') {
this.$refs.jobAnalysisRef.handleChange(this.mode, value)
} else if (this.mode === 'WORKFLOW') {
this.$refs.workFlowAnalysisRef.handleChange(this.mode, value)
}
}
},
created () {
this.mode = storage.get(APP_MODE)
getDashboardTaskRetryJob().then(res => {
this.retryTask = res.data.retryTask
this.jobTask = res.data.jobTask
this.retryTask = res.data.retryTask
this.workFlowTask = res.data.workFlowTask
this.onLineService = res.data.onLineService
this.retryTaskBarList = res.data.retryTaskBarList
})

View File

@ -68,6 +68,7 @@ export default {
dashboardLineResponseDOList: [],
type: 'WEEK',
groupName: '',
mode: '',
startTime: '',
endTime: '',
success: 0,
@ -134,19 +135,22 @@ export default {
},
methods: {
moment,
dataHandler (type) {
dataHandler (mode, type) {
this.mode = mode
this.type = type
this.$refs.jobViewChart.getDashboardJobLine(this.groupName, this.type, this.startTime, this.endTime)
this.$refs.jobViewChart.getDashboardJobLine(this.mode, this.groupName, this.type, this.startTime, this.endTime)
},
handleChange (value) {
handleChange (mode, value) {
this.mode = mode
this.groupName = value
this.$refs.jobViewChart.getDashboardJobLine(this.groupName, this.type, this.startTime, this.endTime)
this.$refs.jobViewChart.getDashboardJobLine(this.mode, this.groupName, this.type, this.startTime, this.endTime)
},
dateChange (date, dateString) {
dateChange (mode, date, dateString) {
this.mode = mode
this.startTime = dateString[0]
this.endTime = dateString[1]
this.type = this.startTime === '' ? 'WEEK' : 'OTHERS'
this.$refs.jobViewChart.getDashboardJobLine(this.groupName, this.type, this.startTime, this.endTime)
this.$refs.jobViewChart.getDashboardJobLine(this.mode, this.groupName, this.type, this.startTime, this.endTime)
}
},
created () {

View File

@ -0,0 +1,170 @@
<template>
<div class="antd-pro-pages-dashboard-analysis-twoColLayout" :class="!isMobile && 'desktop'">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<g2-work-flow-line ref="workFlowViewChart" name="G2WorkFlowLine" />
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="失败任务排名" :list="rankList" />
</a-col>
</a-row>
<a-row :gutter="24" type="flex" :style="{ marginTop: '24px' }">
<a-col :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
<a-card :loading="loading" :bordered="false" :title="$t('dashboard.analysis.online-top-search')" :style="{ height: '100%' }">
<s-table
ref="table"
size="default"
:rowKey="(record,index) => index"
:columns="columns"
:data="loadData"
:scroll="{ x: 200 }"
>
</s-table>
</a-card>
</a-col>
<a-col :xl="12" :lg="24" :md="24" :sm="24" :xs="24">
<a-card class="antd-pro-pages-dashboard-analysis-salesCard" :loading="loading" :bordered="false" :title="$t('dashboard.analysis.the-proportion-of-sales')" :style="{ height: '100%' }">
<h4>{{ $t('dashboard.analysis.job.sales') }}</h4>
<div>
<div>
<v-chart :force-fit="true" :height="405" :data="pieData" :scale="pieScale" >
<v-tooltip :showTitle="false" dataKey="value*percent" />
<v-axis />
<v-legend dataKey="value" />
<v-pie position="percent" color="value" :vStyle="pieStyle" />
<v-coord type="theta" :radius="0.95" :innerRadius="0.7" />
</v-chart>
</div>
</div>
</a-card>
</a-col>
</a-row>
</div>
</template>
<script>
import {
RankList,
STable
} from '@/components'
import { getAllGroupNameList, getDashboardJobLine } from '@/api/manage'
import { baseMixin } from '@/store/app-mixin'
import G2WorkFlowLine from '@/components/Charts/WorkFlowLine.vue'
import moment from 'moment'
export default {
name: 'WorkFlowAnalysis',
mixins: [ baseMixin ],
components: {
G2WorkFlowLine,
RankList,
STable
},
data () {
return {
loading: true,
rankList: [],
taskList: [],
dashboardLineResponseDOList: [],
type: 'WEEK',
groupName: '',
mode: '',
startTime: '',
endTime: '',
success: 0,
fail: 0,
stop: 0,
cancel: 0,
total: 0,
groupNameList: [],
pieScale: [{
dataKey: 'percent',
min: 0,
formatter: '.0%'
}],
pieData: [],
pieStyle: {
stroke: '#fff',
lineWidth: 1
},
columns: [
{
title: '组名称',
dataIndex: 'groupName'
},
{
title: '运行中任务数',
dataIndex: 'run'
},
{
title: '总任务数',
dataIndex: 'total'
}
],
loadData: (parameter) => {
return getDashboardJobLine(Object.assign(parameter)).then((res) => {
this.rankList = res.data.rankList
return res.data.taskList
})
}
}
},
mounted () {
this.$bus.$on('WORKFLOW', (res) => {
this.total = 0
this.success = 0
this.fail = 0
this.stop = 0
this.cancel = 0
this.rankList = res.data.rankList
this.taskList = res.data.taskList
res.data.dashboardLineResponseDOList.forEach(res => {
this.success += res.success
this.fail += res.fail
this.stop += res.stop
this.cancel += res.cancel
})
this.total = this.success + this.fail + this.stop + this.cancel
this.pieData = [
{ value: 'SUCCESS', name: this.success, percent: this.success / this.total },
{ value: 'FAIL', name: this.fail, percent: this.fail / this.total },
{ value: 'STOP', name: this.stop, percent: this.stop / this.total },
{ value: 'CANCEL', name: this.cancel, percent: this.cancel / this.total }
]
})
},
methods: {
moment,
dataHandler (mode, type) {
this.mode = mode
this.type = type
this.$refs.workFlowViewChart.getDashboardJobLine(this.mode, this.groupName, this.type, this.startTime, this.endTime)
},
handleChange (mode, value) {
this.mode = mode
this.groupName = value
this.$refs.workFlowViewChart.getDashboardJobLine(this.mode, this.groupName, this.type, this.startTime, this.endTime)
},
dateChange (mode, date, dateString) {
this.mode = mode
this.startTime = dateString[0]
this.endTime = dateString[1]
this.type = this.startTime === '' ? 'WEEK' : 'OTHERS'
this.$refs.workFlowViewChart.getDashboardJobLine(this.mode, this.groupName, this.type, this.startTime, this.endTime)
}
},
created () {
getAllGroupNameList().then(res => {
this.groupNameList = res.data
})
setTimeout(() => {
this.loading = !this.loading
}, 1000)
}
}
</script>
<style lang='less' scoped>
@import 'Analysis.less';
</style>