9 changed files with 396 additions and 3 deletions
@ -0,0 +1,35 @@ |
|||||||
|
package com.biutag.supervision.pojo.vo; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author kami on 2024-11-16 15:06:25 |
||||||
|
* @version 0.0.1 |
||||||
|
* @since 1.8 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@Slf4j |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor(force = true) |
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||||
|
public class ProblemSourceStatisticsVo implements Serializable { |
||||||
|
|
||||||
|
Integer aTotal; |
||||||
|
|
||||||
|
Integer caseTotal; |
||||||
|
|
||||||
|
Integer negativeTotal; |
||||||
|
|
||||||
|
Integer peopleCount; |
||||||
|
|
||||||
|
Double avgPeople; |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
package com.biutag.supervision.pojo.vo; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Builder; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author kami on 2024-11-16 15:06:25 |
||||||
|
* @version 0.0.1 |
||||||
|
* @since 1.8 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@Builder |
||||||
|
@Slf4j |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor(force = true) |
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||||
|
public class ProblemSourceVo implements Serializable { |
||||||
|
|
||||||
|
String name; |
||||||
|
|
||||||
|
String id; |
||||||
|
|
||||||
|
Integer number; |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,102 @@ |
|||||||
|
package com.biutag.supervision.service; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||||
|
import com.biutag.supervision.mapper.BusinessDepartMapper; |
||||||
|
import com.biutag.supervision.mapper.NegativeBlameMapper; |
||||||
|
import com.biutag.supervision.mapper.NegativeMapper; |
||||||
|
import com.biutag.supervision.mapper.SupDepartMapper; |
||||||
|
import com.biutag.supervision.pojo.entity.BusinessDepart; |
||||||
|
import com.biutag.supervision.pojo.entity.Negative; |
||||||
|
import com.biutag.supervision.pojo.entity.NegativeBlame; |
||||||
|
import com.biutag.supervision.pojo.entity.SupDepart; |
||||||
|
import com.biutag.supervision.pojo.vo.ProblemSourceStatisticsVo; |
||||||
|
import com.biutag.supervision.pojo.vo.ProblemSourceVo; |
||||||
|
import com.biutag.supervision.util.CompletableUtils.CompletableFutureUtil; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.math.RoundingMode; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.time.format.DateTimeFormatter; |
||||||
|
import java.util.*; |
||||||
|
import java.util.concurrent.CompletableFuture; |
||||||
|
import java.util.function.Function; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* 灵敏感知大屏 |
||||||
|
* @author kami on 2024-11-16 15:04:16 |
||||||
|
* @version 0.0.1 |
||||||
|
* @since 1.8 |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
@Service |
||||||
|
@AllArgsConstructor |
||||||
|
public class ProblemSourceService { |
||||||
|
|
||||||
|
private final BusinessDepartMapper businessDepartMapper; |
||||||
|
|
||||||
|
private final NegativeMapper negativeMapper; |
||||||
|
|
||||||
|
private final NegativeBlameMapper blameMapper; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数量统计 |
||||||
|
* @return 统计结构 |
||||||
|
*/ |
||||||
|
public ProblemSourceStatisticsVo totalStatistics() { |
||||||
|
ProblemSourceStatisticsVo.ProblemSourceStatisticsVoBuilder build = ProblemSourceStatisticsVo.builder(); |
||||||
|
CompletableFuture.allOf( |
||||||
|
CompletableFutureUtil.runSyncObject(() -> build.aTotal(businessDepartMapper.problemSum(List.of(1,2), "2024-01-01 00:00:00"))), |
||||||
|
CompletableFutureUtil.runSyncObject(() -> build.caseTotal(businessDepartMapper.problemSum(List.of(4,5,6), "2024-01-01 00:00:00"))), |
||||||
|
CompletableFutureUtil.runSyncObject(() -> build.negativeTotal(negativeMapper.selectCount(new LambdaQueryWrapper<Negative>().in(Negative::getCheckStatus, List.of(1,2))).intValue())) |
||||||
|
).join(); |
||||||
|
List<NegativeBlame> list = blameMapper.selectList(new LambdaQueryWrapper<NegativeBlame>().select(NegativeBlame::getBlameIdCode)); |
||||||
|
Long count = list.stream().map(NegativeBlame::getBlameIdCode).distinct().count(); |
||||||
|
build.peopleCount(count.intValue()); |
||||||
|
ProblemSourceStatisticsVo vo = build.build(); |
||||||
|
vo.setAvgPeople(new BigDecimal(vo.getNegativeTotal().toString()).divide(new BigDecimal(vo.getPeopleCount().toString()), 2, RoundingMode.UP).doubleValue()); |
||||||
|
return vo; |
||||||
|
} |
||||||
|
|
||||||
|
private final SupDepartMapper supDepartMapper; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param type 类型 1- 风险值 2- 问题数 3-问题发生率 |
||||||
|
* @param businessType |
||||||
|
*/ |
||||||
|
public void rankStatistics(Integer type, Integer businessType) { |
||||||
|
List<SupDepart> departs = supDepartMapper.selectList(new LambdaQueryWrapper<SupDepart>() |
||||||
|
.select(SupDepart::getId, SupDepart::getPid, SupDepart::getName, SupDepart::getLevel)); |
||||||
|
Map<String, SupDepart> departMap = departs.stream().collect(Collectors.toMap(SupDepart::getId, Function.identity(), (oldValue, newValue) -> newValue)); |
||||||
|
|
||||||
|
List<Negative> negatives = negativeMapper.selectList(new LambdaQueryWrapper<Negative>() |
||||||
|
.in(Negative::getCheckStatus, List.of(1,2))); |
||||||
|
|
||||||
|
Map<String, Integer> mapLevel3 = new HashMap<>(); |
||||||
|
Map<String, Integer> mapLevel2 = new HashMap<>(); |
||||||
|
|
||||||
|
for (Negative negative : negatives) { |
||||||
|
SupDepart depart = departMap.get(negative.getInvolveDepartId()); |
||||||
|
if(depart == null) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
if(depart.getLevel() == 3) { |
||||||
|
Integer count = Optional.ofNullable(mapLevel3.get(negative.getInvolveDepartId())).orElse(0); |
||||||
|
count++; |
||||||
|
mapLevel3.put(negative.getInvolveDepartId(), count); |
||||||
|
depart = departMap.get(depart.getPid()); |
||||||
|
} |
||||||
|
if(depart.getLevel() == 2) { |
||||||
|
Integer count = Optional.ofNullable(mapLevel2.get(negative.getInvolveDepartId())).orElse(0); |
||||||
|
count++; |
||||||
|
mapLevel2.put(negative.getInvolveDepartId(), count); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.biutag.supervision.util.CompletableUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author kami |
||||||
|
* @version 1.0 |
||||||
|
* @since 2021/11/22 17:37 |
||||||
|
*/ |
||||||
|
@FunctionalInterface |
||||||
|
public interface CompletableFutureMine { |
||||||
|
|
||||||
|
void run(); |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.biutag.supervision.util.CompletableUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author kami |
||||||
|
* @version 1.0 |
||||||
|
* @since 2021/11/22 17:37 |
||||||
|
*/ |
||||||
|
@FunctionalInterface |
||||||
|
public interface CompletableFutureResult { |
||||||
|
|
||||||
|
Boolean run(); |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
package com.biutag.supervision.util.CompletableUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author kami |
||||||
|
* @version 1.0 |
||||||
|
* @since 2021/11/22 17:37 |
||||||
|
*/ |
||||||
|
@FunctionalInterface |
||||||
|
public interface CompletableFutureType<T> { |
||||||
|
|
||||||
|
T run(); |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,164 @@ |
|||||||
|
package com.biutag.supervision.util.CompletableUtils; |
||||||
|
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
import org.slf4j.MDC; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
import java.util.concurrent.CompletableFuture; |
||||||
|
import java.util.concurrent.Executor; |
||||||
|
import java.util.concurrent.Executors; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author kami |
||||||
|
* @version 1.0 |
||||||
|
* @since 2021/11/22 17:39 |
||||||
|
*/ |
||||||
|
@Slf4j |
||||||
|
public class CompletableFutureUtil { |
||||||
|
|
||||||
|
private CompletableFutureUtil(){} |
||||||
|
|
||||||
|
public static final String TRACE_ID = "trace_id"; |
||||||
|
|
||||||
|
private static void run(CompletableFutureMine completableFutureMine, Map<String, String> previous) { |
||||||
|
if (previous == null) { |
||||||
|
MDC.clear(); |
||||||
|
} else { |
||||||
|
MDC.setContextMap(previous); |
||||||
|
} |
||||||
|
if (MDC.get(TRACE_ID) == null || MDC.get(TRACE_ID).isEmpty()) { |
||||||
|
MDC.put(TRACE_ID, System.nanoTime() + ""); |
||||||
|
} |
||||||
|
completableFutureMine.run(); |
||||||
|
MDC.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
private static Boolean runResult(CompletableFutureResult result, Map<String, String> previous) { |
||||||
|
if (previous == null) { |
||||||
|
MDC.clear(); |
||||||
|
} else { |
||||||
|
MDC.setContextMap(previous); |
||||||
|
} |
||||||
|
if (MDC.get(TRACE_ID) == null || MDC.get(TRACE_ID).isEmpty()) { |
||||||
|
MDC.put(TRACE_ID, System.nanoTime() + ""); |
||||||
|
} |
||||||
|
Boolean rs = result.run(); |
||||||
|
MDC.clear(); |
||||||
|
return rs; |
||||||
|
} |
||||||
|
|
||||||
|
public static void runSync(CompletableFutureMine completableFutureMine) { |
||||||
|
Map<String, String> previous = MDC.getCopyOfContextMap(); |
||||||
|
CompletableFuture.runAsync(() -> run(completableFutureMine, previous)).exceptionally(e -> { |
||||||
|
log.error("",e); |
||||||
|
MDC.clear(); |
||||||
|
return null; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public static CompletableFuture runSyncObject(CompletableFutureMine completableFutureMine) { |
||||||
|
Map<String, String> previous = MDC.getCopyOfContextMap(); |
||||||
|
return CompletableFuture.runAsync(() -> { |
||||||
|
if (previous == null) { |
||||||
|
MDC.clear(); |
||||||
|
} else { |
||||||
|
MDC.setContextMap(previous); |
||||||
|
} |
||||||
|
if (MDC.get(TRACE_ID) == null || MDC.get(TRACE_ID).isEmpty()) { |
||||||
|
MDC.put(TRACE_ID, System.nanoTime() + ""); |
||||||
|
} |
||||||
|
run(completableFutureMine, previous); |
||||||
|
MDC.clear(); |
||||||
|
}).exceptionally(e -> { |
||||||
|
log.error("",e); |
||||||
|
MDC.clear(); |
||||||
|
return null; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public static void run(CompletableFutureMine completableFutureMine) { |
||||||
|
Map<String, String> previous = MDC.getCopyOfContextMap(); |
||||||
|
CompletableFuture.runAsync(() -> run(completableFutureMine, previous)).exceptionally(e -> { |
||||||
|
log.error("",e); |
||||||
|
MDC.clear(); |
||||||
|
return null; |
||||||
|
}).join(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void runSyncEach(CompletableFutureResult result, Long time) { |
||||||
|
Map<String, String> previous = MDC.getCopyOfContextMap(); |
||||||
|
CompletableFuture.runAsync(() -> { |
||||||
|
Boolean goOn = true; |
||||||
|
while (Boolean.TRUE.equals(goOn)) { |
||||||
|
try { |
||||||
|
TimeUnit.SECONDS.sleep(time); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
log.error("",e); |
||||||
|
Thread.currentThread().interrupt(); |
||||||
|
} |
||||||
|
goOn = runResult(result, previous); |
||||||
|
} |
||||||
|
}).exceptionally(e -> { |
||||||
|
log.error("",e); |
||||||
|
MDC.clear(); |
||||||
|
return null; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public static void runSyncEach(CompletableFutureResult result, Executor ex, Long time) { |
||||||
|
Map<String, String> previous = MDC.getCopyOfContextMap(); |
||||||
|
CompletableFuture.runAsync(() -> { |
||||||
|
Boolean goOn = true; |
||||||
|
while (goOn) { |
||||||
|
try { |
||||||
|
TimeUnit.SECONDS.sleep(time); |
||||||
|
} catch (InterruptedException e) { |
||||||
|
log.error("",e); |
||||||
|
Thread.currentThread().interrupt(); |
||||||
|
} |
||||||
|
goOn = runResult(result, previous); |
||||||
|
} |
||||||
|
}, ex).exceptionally(e -> { |
||||||
|
log.error("",e); |
||||||
|
MDC.clear(); |
||||||
|
return null; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public static void runSync(CompletableFutureMine completableFutureMine, Executor ex) { |
||||||
|
Map<String, String> previous = MDC.getCopyOfContextMap(); |
||||||
|
CompletableFuture.runAsync(() -> run(completableFutureMine, previous), ex).exceptionally(e -> { |
||||||
|
log.error("", e); |
||||||
|
MDC.clear(); |
||||||
|
return null; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public static void runSyncAssert(Boolean assets, CompletableFutureMine completableFutureMine) { |
||||||
|
if(Boolean.TRUE.equals(assets)) { |
||||||
|
CompletableFuture.runAsync(completableFutureMine::run).exceptionally(e -> { |
||||||
|
log.error("",e); |
||||||
|
return null; |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static <T> CompletableFuture<T> createRunner(CompletableFutureType<T> completableFutureType) { |
||||||
|
Map<String, String> previous = MDC.getCopyOfContextMap(); |
||||||
|
return CompletableFuture.supplyAsync(() -> { |
||||||
|
if (previous == null) { |
||||||
|
MDC.clear(); |
||||||
|
} else { |
||||||
|
MDC.setContextMap(previous); |
||||||
|
} |
||||||
|
if (MDC.get(TRACE_ID) == null || MDC.get(TRACE_ID).isEmpty()) { |
||||||
|
MDC.put(TRACE_ID, System.nanoTime() + ""); |
||||||
|
} |
||||||
|
T t = completableFutureType.run(); |
||||||
|
MDC.clear(); |
||||||
|
return t; |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue