Compare commits
2 Commits
d6e30d4d50
...
d14e5d2a1d
| Author | SHA1 | Date | |
|---|---|---|---|
| d14e5d2a1d | |||
| 017961e3b2 |
@@ -12,6 +12,7 @@ import com.klp.pocket.acid.domain.vo.AcidOeeIdealCycleVo;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeLoss7Vo;
|
||||
import com.klp.pocket.acid.domain.vo.Klptcm1ProStoppageVo;
|
||||
import com.klp.pocket.acid.service.IAcidOeeService;
|
||||
import com.klp.pocket.galvanize1.service.IGalvanizeOeeService;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
|
||||
@@ -61,6 +62,7 @@ import java.util.stream.Collectors;
|
||||
public class OeeReportController extends BaseController {
|
||||
|
||||
private final IAcidOeeService acidOeeService;
|
||||
private final IGalvanizeOeeService galvanizeOeeService;
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
private final OeeReportJobService oeeReportJobService;
|
||||
private final OeeWordAiAnalysisService oeeWordAiAnalysisService;
|
||||
@@ -83,11 +85,13 @@ public class OeeReportController extends BaseController {
|
||||
@GetMapping("/acid/summary")
|
||||
public R<List<AcidOeeDailySummaryVo>> getAcidSummary(
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate
|
||||
@RequestParam(required = false) String endDate,
|
||||
@RequestParam(required = false, defaultValue = "acid") String lineType
|
||||
) {
|
||||
String[] range = resolveDateRange(startDate, endDate);
|
||||
List<AcidOeeDailySummaryVo> dailyList =
|
||||
acidOeeService.getDailySummary(range[0], range[1]);
|
||||
List<AcidOeeDailySummaryVo> dailyList = isGalvanize(lineType)
|
||||
? galvanizeOeeService.getDailySummary(range[0], range[1])
|
||||
: acidOeeService.getDailySummary(range[0], range[1]);
|
||||
return R.ok(dailyList);
|
||||
}
|
||||
|
||||
@@ -101,21 +105,15 @@ public class OeeReportController extends BaseController {
|
||||
*/
|
||||
@GetMapping("/acid/loss7")
|
||||
public R<List<AcidOeeLoss7Vo>> getAcidLoss7(
|
||||
@RequestParam(required = false, defaultValue = "50") Integer topN
|
||||
@RequestParam(required = false, defaultValue = "50") Integer topN,
|
||||
@RequestParam(required = false) String startDate,
|
||||
@RequestParam(required = false) String endDate,
|
||||
@RequestParam(required = false, defaultValue = "acid") String lineType
|
||||
) {
|
||||
String yyyyMM = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
|
||||
String loss7Key = String.format("oee:report:month:loss7:%s:SY", yyyyMM);
|
||||
|
||||
// 1. 优先从 Redis 读取当月 7 大损失预计算结果
|
||||
String json = stringRedisTemplate.opsForValue().get(loss7Key);
|
||||
List<AcidOeeLoss7Vo> lossList;
|
||||
if (StringUtils.isNotBlank(json)) {
|
||||
lossList = JSON.parseArray(json, AcidOeeLoss7Vo.class);
|
||||
} else {
|
||||
// 2. 缓存缺失时,回退为实时计算当前月
|
||||
String[] range = resolveDateRange(null, null);
|
||||
lossList = acidOeeService.getLoss7Summary(range[0], range[1]);
|
||||
}
|
||||
String[] range = resolveDateRange(startDate, endDate);
|
||||
List<AcidOeeLoss7Vo> lossList = isGalvanize(lineType)
|
||||
? galvanizeOeeService.getLoss7Summary(range[0], range[1])
|
||||
: acidOeeService.getLoss7Summary(range[0], range[1]);
|
||||
|
||||
if (topN != null && topN > 0 && lossList.size() > topN) {
|
||||
lossList = new ArrayList<>(lossList.subList(0, topN));
|
||||
@@ -139,14 +137,16 @@ public class OeeReportController extends BaseController {
|
||||
@RequestParam(required = false) String stopType,
|
||||
@RequestParam(required = false) String keyword,
|
||||
@RequestParam(required = false, defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize
|
||||
@RequestParam(required = false, defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false, defaultValue = "acid") String lineType
|
||||
) {
|
||||
// 事件明细底层按「日期」查询,这里从时间字符串中截取日期部分
|
||||
String startDate = extractDateOrDefault(startTime, true);
|
||||
String endDate = extractDateOrDefault(endTime, false);
|
||||
|
||||
List<Klptcm1ProStoppageVo> events =
|
||||
acidOeeService.getStoppageEvents(startDate, endDate);
|
||||
List<Klptcm1ProStoppageVo> events = isGalvanize(lineType)
|
||||
? galvanizeOeeService.getStoppageEvents(startDate, endDate)
|
||||
: acidOeeService.getStoppageEvents(startDate, endDate);
|
||||
|
||||
// 业务筛选:stopType、关键字(目前对 stopType / remark 做 contains 匹配)
|
||||
List<Klptcm1ProStoppageVo> filtered = events.stream()
|
||||
@@ -192,9 +192,12 @@ public class OeeReportController extends BaseController {
|
||||
@GetMapping("/acid/idealCycle")
|
||||
public R<AcidOeeIdealCycleVo> getAcidIdealCycle(
|
||||
@RequestParam String startDate,
|
||||
@RequestParam String endDate
|
||||
@RequestParam String endDate,
|
||||
@RequestParam(required = false, defaultValue = "acid") String lineType
|
||||
) {
|
||||
AcidOeeIdealCycleVo data = acidOeeService.getIdealCycle(startDate, endDate);
|
||||
AcidOeeIdealCycleVo data = isGalvanize(lineType)
|
||||
? galvanizeOeeService.getIdealCycle(startDate, endDate)
|
||||
: acidOeeService.getIdealCycle(startDate, endDate);
|
||||
return R.ok(data);
|
||||
}
|
||||
|
||||
@@ -415,6 +418,10 @@ public class OeeReportController extends BaseController {
|
||||
/**
|
||||
* 若未显式传入日期范围,则默认当前月 [1号, 今天]。
|
||||
*/
|
||||
private boolean isGalvanize(String lineType) {
|
||||
return "galvanize1".equalsIgnoreCase(lineType) || "galvanize".equalsIgnoreCase(lineType) || "dx".equalsIgnoreCase(lineType);
|
||||
}
|
||||
|
||||
private String[] resolveDateRange(String startDate, String endDate) {
|
||||
if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
|
||||
return new String[]{startDate, endDate};
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.klp.pocket.galvanize1.mapper;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeCoilInfoByDateVo;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeDailySummaryVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
@DS("master")
|
||||
public interface GalvanizeOeeMasterMapper {
|
||||
|
||||
List<AcidOeeDailySummaryVo> selectDailySummary(@Param("startDate") String startDate,
|
||||
@Param("endDate") String endDate,
|
||||
@Param("createBy") String createBy);
|
||||
|
||||
List<AcidOeeCoilInfoByDateVo> selectCoilInfoByDate(@Param("startDate") String startDate,
|
||||
@Param("endDate") String endDate,
|
||||
@Param("createBy") String createBy);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.klp.pocket.galvanize1.service;
|
||||
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeDailySummaryVo;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeIdealCycleVo;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeLoss7Vo;
|
||||
import com.klp.pocket.acid.domain.vo.Klptcm1ProStoppageVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IGalvanizeOeeService {
|
||||
|
||||
List<AcidOeeDailySummaryVo> getDailySummary(String startDate, String endDate);
|
||||
|
||||
List<Klptcm1ProStoppageVo> getStoppageEvents(String startDate, String endDate);
|
||||
|
||||
List<AcidOeeLoss7Vo> getLoss7Summary(String startDate, String endDate);
|
||||
|
||||
AcidOeeIdealCycleVo getIdealCycle(String startDate, String endDate);
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
package com.klp.pocket.galvanize1.service.impl;
|
||||
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeCoilInfoByDateVo;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeDailySummaryVo;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeIdealCycleVo;
|
||||
import com.klp.pocket.acid.domain.vo.AcidOeeLoss7Vo;
|
||||
import com.klp.pocket.acid.domain.vo.Klptcm1ProStoppageVo;
|
||||
import com.klp.pocket.galvanize1.domain.bo.ProStoppageBo;
|
||||
import com.klp.pocket.galvanize1.domain.vo.ProStoppageVo;
|
||||
import com.klp.pocket.galvanize1.mapper.GalvanizeOeeMasterMapper;
|
||||
import com.klp.pocket.galvanize1.service.IGalvanizeOeeService;
|
||||
import com.klp.pocket.galvanize1.service.IProStoppageService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class GalvanizeOeeServiceImpl implements IGalvanizeOeeService {
|
||||
|
||||
private static final Set<String> CD_SERIES = new HashSet<>(Arrays.asList("C+", "C", "C-", "D+", "D", "D-"));
|
||||
|
||||
private final GalvanizeOeeMasterMapper galvanizeOeeMasterMapper;
|
||||
private final IProStoppageService proStoppageService;
|
||||
|
||||
@Value("${oee.galvanize1.coil-create-by:duxinkuguan}")
|
||||
private String galvanizeCreateBy;
|
||||
|
||||
@Override
|
||||
public List<AcidOeeDailySummaryVo> getDailySummary(String startDate, String endDate) {
|
||||
List<AcidOeeDailySummaryVo> summaries = galvanizeOeeMasterMapper.selectDailySummary(startDate, endDate, galvanizeCreateBy);
|
||||
if (summaries == null || summaries.isEmpty()) return Collections.emptyList();
|
||||
|
||||
Map<String, Long> downtimeByDate = aggregateDowntimeByDate(startDate, endDate);
|
||||
Map<String, List<CoilInfo>> coilInfoByDate = getCoilNosByDate(startDate, endDate);
|
||||
|
||||
List<BigDecimal> dailyCycles = new ArrayList<>();
|
||||
for (AcidOeeDailySummaryVo s : summaries) {
|
||||
s.setLineId("DX1");
|
||||
s.setLineName("镀锌一线");
|
||||
Long downtime = downtimeByDate.getOrDefault(s.getStatDate(), 0L);
|
||||
s.setDowntimeMin(downtime);
|
||||
Long loading = s.getLoadingTimeMin() == null ? 0L : s.getLoadingTimeMin();
|
||||
Long run = Math.max(0, loading - downtime);
|
||||
s.setRunTimeMin(run);
|
||||
BigDecimal ton = s.getTotalOutputTon();
|
||||
if (run > 0 && ton != null && ton.compareTo(BigDecimal.ZERO) > 0) {
|
||||
dailyCycles.add(BigDecimal.valueOf(run).divide(ton, 6, RoundingMode.HALF_UP));
|
||||
}
|
||||
}
|
||||
dailyCycles.sort(BigDecimal::compareTo);
|
||||
BigDecimal ideal = applyEightyPercent(median(dailyCycles));
|
||||
|
||||
for (AcidOeeDailySummaryVo s : summaries) {
|
||||
if (ideal != null) s.setIdealCycleTimeMinPerTon(ideal);
|
||||
List<CoilInfo> coilInfos = coilInfoByDate.get(s.getStatDate());
|
||||
if (coilInfos != null) {
|
||||
calculateQualityOutput(s, coilInfos);
|
||||
} else {
|
||||
s.setGoodOutputTon(BigDecimal.ZERO);
|
||||
s.setGoodOutputCoil(0L);
|
||||
s.setQualifiedOutputTon(BigDecimal.ZERO);
|
||||
s.setQualifiedOutputCoil(0L);
|
||||
s.setAbOutputTon(BigDecimal.ZERO);
|
||||
s.setAbOutputCoil(0L);
|
||||
s.setDefectOutputTon(BigDecimal.ZERO);
|
||||
s.setDefectOutputCoil(0L);
|
||||
s.setPendingOutputTon(s.getTotalOutputTon());
|
||||
s.setPendingOutputCoil(s.getTotalOutputCoil());
|
||||
}
|
||||
calculateDerivedMetrics(s);
|
||||
}
|
||||
return summaries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Klptcm1ProStoppageVo> getStoppageEvents(String startDate, String endDate) {
|
||||
ProStoppageBo bo = new ProStoppageBo();
|
||||
bo.setStartDate(parseDate(startDate));
|
||||
bo.setEndDate(parseDate(endDate));
|
||||
List<ProStoppageVo> list = proStoppageService.queryList(bo);
|
||||
List<Klptcm1ProStoppageVo> out = new ArrayList<>();
|
||||
for (ProStoppageVo p : list) {
|
||||
Klptcm1ProStoppageVo v = new Klptcm1ProStoppageVo();
|
||||
v.setStopid(p.getStopid());
|
||||
v.setShift(p.getShift());
|
||||
v.setCrew(p.getCrew());
|
||||
v.setArea(p.getArea());
|
||||
v.setUnit(p.getUnit());
|
||||
v.setSeton(p.getSeton());
|
||||
v.setStartDate(p.getStartDate());
|
||||
v.setEndDate(p.getEndDate());
|
||||
v.setRemark(p.getRemark());
|
||||
v.setStopType(p.getStopType());
|
||||
long durationSec = p.getDuration() == null ? 0L : Math.round(p.getDuration());
|
||||
v.setDuration(durationSec);
|
||||
out.add(v);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AcidOeeLoss7Vo> getLoss7Summary(String startDate, String endDate) {
|
||||
List<Klptcm1ProStoppageVo> events = getStoppageEvents(startDate, endDate);
|
||||
if (events.isEmpty()) return Collections.emptyList();
|
||||
Map<String, long[]> m = new HashMap<>();
|
||||
long total = 0L;
|
||||
for (Klptcm1ProStoppageVo e : events) {
|
||||
String k = StringUtils.isBlank(e.getStopType()) ? "未分类" : e.getStopType();
|
||||
long min = Math.max(1, (e.getDuration() == null ? 0L : e.getDuration()) / 60);
|
||||
if (min <= 0) continue;
|
||||
m.computeIfAbsent(k, x -> new long[2]);
|
||||
m.get(k)[0] += min;
|
||||
m.get(k)[1] += 1;
|
||||
total += min;
|
||||
}
|
||||
List<AcidOeeLoss7Vo> out = new ArrayList<>();
|
||||
for (Map.Entry<String, long[]> en : m.entrySet()) {
|
||||
AcidOeeLoss7Vo vo = new AcidOeeLoss7Vo();
|
||||
vo.setLossCategoryCode(en.getKey());
|
||||
vo.setLossCategoryName(en.getKey());
|
||||
vo.setLossTimeMin(en.getValue()[0]);
|
||||
vo.setCount((int) en.getValue()[1]);
|
||||
vo.setAvgDurationMin(BigDecimal.valueOf(en.getValue()[0]).divide(BigDecimal.valueOf(Math.max(1, en.getValue()[1])), 2, RoundingMode.HALF_UP));
|
||||
vo.setLossTimeRate(total == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(en.getValue()[0]).divide(BigDecimal.valueOf(total), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
out.add(vo);
|
||||
}
|
||||
out.sort(Comparator.comparingLong(AcidOeeLoss7Vo::getLossTimeMin).reversed());
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AcidOeeIdealCycleVo getIdealCycle(String startDate, String endDate) {
|
||||
List<AcidOeeDailySummaryVo> daily = getDailySummary(startDate, endDate);
|
||||
AcidOeeIdealCycleVo rsp = new AcidOeeIdealCycleVo();
|
||||
rsp.setLineId("DX1");
|
||||
rsp.setLineName("镀锌一线");
|
||||
rsp.setStartDate(startDate);
|
||||
rsp.setEndDate(endDate);
|
||||
if (daily.isEmpty()) {
|
||||
rsp.setDailyComparePoints(Collections.emptyList());
|
||||
rsp.setSampleDays(0);
|
||||
return rsp;
|
||||
}
|
||||
List<BigDecimal> dailyCycles = new ArrayList<>();
|
||||
List<AcidOeeIdealCycleVo.DailyComparePointVo> points = new ArrayList<>();
|
||||
for (AcidOeeDailySummaryVo d : daily) {
|
||||
if (d.getRunTimeMin() == null || d.getRunTimeMin() <= 0 || d.getTotalOutputTon() == null || d.getTotalOutputTon().compareTo(BigDecimal.ZERO) <= 0) continue;
|
||||
BigDecimal c = BigDecimal.valueOf(d.getRunTimeMin()).divide(d.getTotalOutputTon(), 6, RoundingMode.HALF_UP);
|
||||
dailyCycles.add(c);
|
||||
}
|
||||
dailyCycles.sort(BigDecimal::compareTo);
|
||||
BigDecimal med = median(dailyCycles);
|
||||
BigDecimal ideal = applyEightyPercent(med);
|
||||
for (AcidOeeDailySummaryVo d : daily) {
|
||||
if (ideal == null || d.getTotalOutputTon() == null || d.getRunTimeMin() == null) continue;
|
||||
AcidOeeIdealCycleVo.DailyComparePointVo p = new AcidOeeIdealCycleVo.DailyComparePointVo();
|
||||
p.setStatDate(d.getStatDate());
|
||||
p.setActualRunTimeMin(d.getRunTimeMin());
|
||||
p.setTheoreticalTimeMin(ideal.multiply(d.getTotalOutputTon()));
|
||||
points.add(p);
|
||||
}
|
||||
rsp.setIdealCycleTimeMinPerTon(ideal);
|
||||
rsp.setMedianCycleTimeMinPerTon(med);
|
||||
rsp.setSampleDays(daily.size());
|
||||
rsp.setDailyComparePoints(points);
|
||||
return rsp;
|
||||
}
|
||||
|
||||
private Map<String, List<CoilInfo>> getCoilNosByDate(String startDate, String endDate) {
|
||||
List<AcidOeeCoilInfoByDateVo> list = galvanizeOeeMasterMapper.selectCoilInfoByDate(startDate, endDate, galvanizeCreateBy);
|
||||
Map<String, List<CoilInfo>> map = new HashMap<>();
|
||||
for (AcidOeeCoilInfoByDateVo i : list) {
|
||||
map.computeIfAbsent(i.getStatDate(), k -> new ArrayList<>()).add(new CoilInfo(i.getWeight(), i.getQualityStatus()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void calculateQualityOutput(AcidOeeDailySummaryVo summary, List<CoilInfo> coilInfos) {
|
||||
BigDecimal aTon = BigDecimal.ZERO, bTon = BigDecimal.ZERO, cdTon = BigDecimal.ZERO, oTon = BigDecimal.ZERO;
|
||||
long a = 0, b = 0, cd = 0, o = 0;
|
||||
for (CoilInfo c : coilInfos) {
|
||||
BigDecimal w = c.weight == null ? BigDecimal.ZERO : c.weight;
|
||||
String q = StringUtils.upperCase(StringUtils.trim(c.qualityStatus));
|
||||
if (StringUtils.isBlank(q) || "O".equals(q)) {
|
||||
oTon = oTon.add(w); o++; continue;
|
||||
}
|
||||
if (q.startsWith("A")) { aTon = aTon.add(w); a++; }
|
||||
else if (q.startsWith("B")) { bTon = bTon.add(w); b++; }
|
||||
else if (CD_SERIES.contains(q)) { cdTon = cdTon.add(w); cd++; }
|
||||
else { oTon = oTon.add(w); o++; }
|
||||
}
|
||||
summary.setGoodOutputTon(aTon); summary.setGoodOutputCoil(a);
|
||||
summary.setQualifiedOutputTon(bTon); summary.setQualifiedOutputCoil(b);
|
||||
summary.setAbOutputTon(aTon.add(bTon)); summary.setAbOutputCoil(a + b);
|
||||
summary.setDefectOutputTon(cdTon); summary.setDefectOutputCoil(cd);
|
||||
summary.setPendingOutputTon(oTon); summary.setPendingOutputCoil(o);
|
||||
}
|
||||
|
||||
private void calculateDerivedMetrics(AcidOeeDailySummaryVo s) {
|
||||
long loading = s.getLoadingTimeMin() == null ? 0 : s.getLoadingTimeMin();
|
||||
long downtime = s.getDowntimeMin() == null ? 0 : s.getDowntimeMin();
|
||||
if (loading > 0) s.setAvailability(BigDecimal.valueOf(loading - downtime).divide(BigDecimal.valueOf(loading), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
long run = s.getRunTimeMin() == null ? 0 : s.getRunTimeMin();
|
||||
BigDecimal ideal = s.getIdealCycleTimeMinPerTon();
|
||||
BigDecimal ton = s.getTotalOutputTon();
|
||||
if (run > 0 && ideal != null && ideal.compareTo(BigDecimal.ZERO) > 0 && ton != null && ton.compareTo(BigDecimal.ZERO) > 0) {
|
||||
s.setPerformanceTon(ideal.multiply(ton).divide(BigDecimal.valueOf(run), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
}
|
||||
if (ton != null && ton.compareTo(BigDecimal.ZERO) > 0) {
|
||||
BigDecimal a = Optional.ofNullable(s.getGoodOutputTon()).orElse(BigDecimal.ZERO);
|
||||
BigDecimal b = Optional.ofNullable(s.getQualifiedOutputTon()).orElse(BigDecimal.ZERO);
|
||||
BigDecimal cd = Optional.ofNullable(s.getDefectOutputTon()).orElse(BigDecimal.ZERO);
|
||||
BigDecimal o = Optional.ofNullable(s.getPendingOutputTon()).orElse(BigDecimal.ZERO);
|
||||
s.setQuality(a.divide(ton, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
s.setQualifiedRate(a.add(b).divide(ton, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
s.setDefectRate(cd.divide(ton, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
s.setPendingRate(o.divide(ton, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
}
|
||||
if (s.getAvailability() != null && s.getPerformanceTon() != null && s.getQuality() != null) {
|
||||
s.setOee(s.getAvailability().multiply(s.getPerformanceTon()).multiply(s.getQuality()).divide(BigDecimal.valueOf(10000), 4, RoundingMode.HALF_UP));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Long> aggregateDowntimeByDate(String startDate, String endDate) {
|
||||
List<Klptcm1ProStoppageVo> events = getStoppageEvents(startDate, endDate);
|
||||
Map<String, Long> map = new HashMap<>();
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
|
||||
for (Klptcm1ProStoppageVo e : events) {
|
||||
if (e.getStartDate() == null || e.getDuration() == null || e.getDuration() <= 0) continue;
|
||||
long min = Math.max(1, (e.getDuration() + 59) / 60);
|
||||
map.merge(df.format(e.getStartDate()), min, Long::sum);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private BigDecimal median(List<BigDecimal> values) {
|
||||
if (values == null || values.isEmpty()) return null;
|
||||
int n = values.size();
|
||||
if (n % 2 == 1) return values.get(n / 2);
|
||||
return values.get(n / 2 - 1).add(values.get(n / 2)).divide(BigDecimal.valueOf(2), 6, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private BigDecimal applyEightyPercent(BigDecimal v) {
|
||||
return v == null ? null : v.multiply(BigDecimal.valueOf(0.7)).setScale(6, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private Date parseDate(String dateStr) {
|
||||
if (StringUtils.isBlank(dateStr)) return null;
|
||||
try {
|
||||
return new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CoilInfo {
|
||||
final BigDecimal weight;
|
||||
final String qualityStatus;
|
||||
|
||||
CoilInfo(BigDecimal weight, String qualityStatus) {
|
||||
this.weight = weight;
|
||||
this.qualityStatus = qualityStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.klp.pocket.galvanize1.mapper.GalvanizeOeeMasterMapper">
|
||||
|
||||
<resultMap id="AcidOeeDailySummaryResultMap" type="com.klp.pocket.acid.domain.vo.AcidOeeDailySummaryVo">
|
||||
<result column="stat_date" property="statDate" jdbcType="VARCHAR"/>
|
||||
<result column="line_id" property="lineId" jdbcType="VARCHAR"/>
|
||||
<result column="line_name" property="lineName" jdbcType="VARCHAR"/>
|
||||
<result column="planned_time_min" property="plannedTimeMin" jdbcType="BIGINT"/>
|
||||
<result column="planned_downtime_min" property="plannedDowntimeMin" jdbcType="BIGINT"/>
|
||||
<result column="loading_time_min" property="loadingTimeMin" jdbcType="BIGINT"/>
|
||||
<result column="downtime_min" property="downtimeMin" jdbcType="BIGINT"/>
|
||||
<result column="run_time_min" property="runTimeMin" jdbcType="BIGINT"/>
|
||||
<result column="total_output_ton" property="totalOutputTon" jdbcType="DECIMAL"/>
|
||||
<result column="total_output_coil" property="totalOutputCoil" jdbcType="BIGINT"/>
|
||||
<result column="good_output_ton" property="goodOutputTon" jdbcType="DECIMAL"/>
|
||||
<result column="good_output_coil" property="goodOutputCoil" jdbcType="BIGINT"/>
|
||||
<result column="defect_output_ton" property="defectOutputTon" jdbcType="DECIMAL"/>
|
||||
<result column="defect_output_coil" property="defectOutputCoil" jdbcType="BIGINT"/>
|
||||
<result column="ideal_cycle_time_min_per_ton" property="idealCycleTimeMinPerTon" jdbcType="DECIMAL"/>
|
||||
<result column="ideal_cycle_time_min_per_coil" property="idealCycleTimeMinPerCoil" jdbcType="DECIMAL"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectDailySummary" resultMap="AcidOeeDailySummaryResultMap">
|
||||
SELECT
|
||||
DATE_FORMAT(mc.create_time, '%Y-%m-%d') AS stat_date,
|
||||
'DX1' AS line_id,
|
||||
'镀锌一线' AS line_name,
|
||||
1440 AS planned_time_min,
|
||||
0 AS planned_downtime_min,
|
||||
1440 AS loading_time_min,
|
||||
0 AS downtime_min,
|
||||
COALESCE(SUM(mc.net_weight / 1000), 0) AS total_output_ton,
|
||||
COUNT(*) AS total_output_coil,
|
||||
0 AS good_output_ton,
|
||||
0 AS good_output_coil,
|
||||
0 AS defect_output_ton,
|
||||
0 AS defect_output_coil,
|
||||
NULL AS ideal_cycle_time_min_per_ton,
|
||||
NULL AS ideal_cycle_time_min_per_coil
|
||||
FROM wms_material_coil mc
|
||||
WHERE DATE(mc.create_time) BETWEEN #{startDate} AND #{endDate}
|
||||
AND mc.create_by = #{createBy}
|
||||
AND mc.del_flag = 0
|
||||
AND mc.data_type = 1
|
||||
AND mc.current_coil_no IS NOT NULL
|
||||
AND mc.net_weight IS NOT NULL
|
||||
AND mc.net_weight > 0
|
||||
GROUP BY DATE_FORMAT(mc.create_time, '%Y-%m-%d')
|
||||
ORDER BY stat_date ASC
|
||||
</select>
|
||||
|
||||
<select id="selectCoilInfoByDate" resultType="com.klp.pocket.acid.domain.vo.AcidOeeCoilInfoByDateVo">
|
||||
SELECT
|
||||
DATE_FORMAT(mc.create_time, '%Y-%m-%d') AS statDate,
|
||||
mc.current_coil_no AS coilNo,
|
||||
(mc.net_weight / 1000) AS weight,
|
||||
mc.quality_status AS qualityStatus
|
||||
FROM wms_material_coil mc
|
||||
WHERE DATE(mc.create_time) BETWEEN #{startDate} AND #{endDate}
|
||||
AND mc.create_by = #{createBy}
|
||||
AND mc.del_flag = 0
|
||||
AND mc.data_type = 1
|
||||
AND mc.current_coil_no IS NOT NULL
|
||||
AND mc.net_weight IS NOT NULL
|
||||
AND mc.net_weight > 0
|
||||
ORDER BY mc.create_time ASC, mc.current_coil_no ASC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -12,6 +12,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="oee-query-bar">
|
||||
<el-select v-model="lineType" size="small" style="width: 120px">
|
||||
<el-option label="酸轧线" value="acid" />
|
||||
<el-option label="镀锌一线" value="galvanize1" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-model="queryRange"
|
||||
type="daterange"
|
||||
@@ -48,6 +52,15 @@
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-alert
|
||||
v-if="lineType === 'galvanize1'"
|
||||
title="镀锌二级数据未完全使用,故而停机时间可能有错误"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
class="oee-top-warning"
|
||||
show-icon
|
||||
/>
|
||||
|
||||
<el-row :gutter="16" class="oee-main-row">
|
||||
<!-- 左侧:报表主体(Word 风格) -->
|
||||
<el-col :span="18">
|
||||
@@ -383,6 +396,7 @@ export default {
|
||||
const today = new Date()
|
||||
const firstDay = new Date(today.getFullYear(), today.getMonth(), 1)
|
||||
return {
|
||||
lineType: 'acid',
|
||||
queryRange: [
|
||||
this.formatDate(firstDay),
|
||||
this.formatDate(today)
|
||||
@@ -542,6 +556,7 @@ export default {
|
||||
buildQuery() {
|
||||
const [start, end] = this.queryRange || []
|
||||
return {
|
||||
lineType: this.lineType,
|
||||
startDate: start,
|
||||
endDate: end
|
||||
}
|
||||
@@ -734,6 +749,10 @@ export default {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.oee-top-warning {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.oee-main-row {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user