feat(): 电文逻辑完善
This commit is contained in:
@@ -1,15 +1,10 @@
|
|||||||
package com.fizz.business.comm.OPC;
|
package com.fizz.business.comm.OPC;
|
||||||
|
|
||||||
import com.fizz.business.constants.enums.OpcMessageType;
|
|
||||||
import com.fizz.business.domain.msg.AppMeasureMessage;
|
|
||||||
import com.kangaroohy.milo.model.ReadWriteEntity;
|
|
||||||
import com.kangaroohy.milo.service.MiloService;
|
import com.kangaroohy.milo.service.MiloService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.compress.utils.Lists;
|
import org.apache.commons.compress.utils.Lists;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.ApplicationArguments;
|
import org.springframework.boot.ApplicationArguments;
|
||||||
import org.springframework.boot.ApplicationRunner;
|
import org.springframework.boot.ApplicationRunner;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.fizz.business.constants;
|
|||||||
|
|
||||||
import com.fizz.business.constants.enums.DeviceEnum;
|
import com.fizz.business.constants.enums.DeviceEnum;
|
||||||
|
|
||||||
import static com.fizz.business.constants.enums.DeviceEnum.DISC;
|
import static com.fizz.business.constants.enums.DeviceEnum.INS;
|
||||||
|
|
||||||
public class CommonConstants {
|
public class CommonConstants {
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ public class CommonConstants {
|
|||||||
public static final String SEG_STRIP_LEN = "SEG_STRIP_LEN";
|
public static final String SEG_STRIP_LEN = "SEG_STRIP_LEN";
|
||||||
|
|
||||||
//卷取机前一个设备idx
|
//卷取机前一个设备idx
|
||||||
public static final DeviceEnum BEFORE_TR_IDX = DISC;
|
public static final DeviceEnum BEFORE_TR_IDX = INS;
|
||||||
|
|
||||||
// 工艺规程点位代码
|
// 工艺规程点位代码
|
||||||
public static final String SETUP_POINT_CODE = "SETUP_POINT_CODE";
|
public static final String SETUP_POINT_CODE = "SETUP_POINT_CODE";
|
||||||
|
|||||||
@@ -5,57 +5,52 @@ import com.fasterxml.jackson.annotation.JsonValue;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
/**
|
||||||
|
* 细粒度设备枚举(按你给出的17台设备)
|
||||||
|
* position 为基准位置(单位:m),用于和 stripLocation 比较。
|
||||||
|
* paramFields 列出该设备需要采样/缓存的字段名(与 AppMeasure*Message 中字段名对应)。
|
||||||
|
*/
|
||||||
public enum DeviceEnum {
|
public enum DeviceEnum {
|
||||||
POR1(0, "1#开卷机"),
|
POR1(0, "1#开卷机", 0.0, Arrays.asList("tensionPorBr1", "stripSpeed")),
|
||||||
POR2(1, "2#开卷机"),
|
POR2(1, "2#开卷机", 1.0, Arrays.asList("tensionPorBr2", "stripSpeed")),
|
||||||
WELDER(2, "焊机"),
|
WELDER(2, "焊机", 5.0, Arrays.asList("weldStatus")),
|
||||||
BR1(3, "1#张力辊"),
|
ENL1(3, "入口活套1", 10.0, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||||
CEL(4, "入口活套"),
|
ENL2(4, "入口活套2", 12.0, Arrays.asList("celLength", "celCapacity", "tensionCel")),
|
||||||
BR2(5, "2#张力辊"),
|
CLEAN(5, "清洗段", 20.0, Arrays.asList("cleaningVoltage", "cleaningCurrent", "alkaliConcentration", "alkaliTemperature")),
|
||||||
ALKALI(6, "碱洗"),
|
FUR1(6, "退火炉-预热段", 30.0, Arrays.asList("phfExitStripTemp","potTemperature","gasConsumption")),
|
||||||
DRYING(7, "热烘干"),
|
FUR2(7, "退火炉-加热段", 40.0, Arrays.asList("rtfExitStripTemp","zincPotPower")),
|
||||||
BR4(8, "4#张力辊"),
|
FUR3(8, "退火炉-冷却段", 50.0, Arrays.asList("jcsExitStripTemp","coolingTowerStripTemp")),
|
||||||
RTF(9, "加热炉"),
|
FUR4(9, "退火炉-均衡段", 60.0, Arrays.asList("scsExitStripTemp")),
|
||||||
SF1(10, "均热炉1"),
|
TM(10, "光整机", 70.0, Arrays.asList("tensionBr5Tm", "stripSpeedTmExit")),
|
||||||
EHF(11, "EHF"),
|
TL(11, "拉矫机", 80.0, Arrays.asList("tlElongation", "tensionTlBr7")),
|
||||||
SF2(12, "均热炉2"),
|
COAT(12, "后处理段", 90.0, Arrays.asList(
|
||||||
CTF(13, "CTF"),
|
"avrCoatingWeightTop","stdCoatingWeightTop","maxCoatingWeightTop","minCoatingWeightTop",
|
||||||
SF3(14, "均热炉3"),
|
"avrCoatingWeightBottom","stdCoatingWeightBottom","maxCoatingWeightBottom","minCoatingWeightBottom",
|
||||||
RJC(15, "控冷段"),
|
"airKnifePressure","airKnifeFlow","airKnifeGap","stripSpeedTmExit","tensionBr5Tm",
|
||||||
AJC(16, "快冷段"),
|
"tensionTmBr6","tensionBr5Br6","tmMask","tmElongation","rollForceOperator","rollForceDrive",
|
||||||
BR5(17, "5#张力辊"),
|
"motorTorque","bendingForce","antiCrimpingRollMesh","billyRollMesh",
|
||||||
BR6(18, "6#张力辊"),
|
"tensionTlBr7","tensionBr6Br7","tlFlag","tlElongation","levelingUnit1Mesh","levelingUnit2Mesh",
|
||||||
CXL(19, "出口活套"),
|
"antiCrossBowUnitMesh","tensionBr7Br8","stripSpeedAfp","stripTempAfp"
|
||||||
BR7(20, "7#张力辊"),
|
)),
|
||||||
BR8(21, "8#张力辊"),
|
CXL1(13, "出口活套1", 100.0, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||||
COAT(22, "涂机"),
|
CXL2(14, "出口活套2", 102.0, Arrays.asList("cxlLength", "cxlCapacity", "tensionCxl")),
|
||||||
DISC(23, "圆盘剪"),
|
INS(15, "检查站", 110.0, Arrays.asList("inspectionStatus")),
|
||||||
TR1(24, "1#卷取机"),
|
TR(16, "卷取机", 120.0, Arrays.asList("coilLength", "speedExitSection", "tensionBr9Tr")),
|
||||||
TR2(25, "2#卷取机");
|
EXC(17, "卸卷小车", 999999.0, Collections.emptyList()),
|
||||||
|
WEIGHT(18, "称重鞍座", 999999.0, Collections.emptyList());
|
||||||
|
|
||||||
|
private final int idx;
|
||||||
private final Integer idx;
|
|
||||||
private final String desc;
|
private final String desc;
|
||||||
private static final Map<String, DeviceEnum> MAP = new HashMap<>();
|
private final double basePosition;
|
||||||
|
private final List<String> paramFields;
|
||||||
|
|
||||||
|
private static final Map<String, DeviceEnum> NAME_MAP = new HashMap<>();
|
||||||
static {
|
static {
|
||||||
for (DeviceEnum e : DeviceEnum.values()) {
|
for (DeviceEnum d : values()) NAME_MAP.put(d.name(), d);
|
||||||
MAP.put(e.getValue(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
public static DeviceEnum fromName(String name) { return NAME_MAP.get(name); }
|
||||||
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
|
}
|
||||||
public static DeviceEnum getByValue(String value) {
|
|
||||||
return MAP.get(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonValue
|
|
||||||
public String getValue() {
|
|
||||||
return this.name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -57,8 +57,7 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
|||||||
@Override
|
@Override
|
||||||
public void operate(L1OperateMatForm form) {
|
public void operate(L1OperateMatForm form) {
|
||||||
PRODUCING.syncPlanStatus(form.getPlanId());
|
PRODUCING.syncPlanStatus(form.getPlanId());
|
||||||
// 钢卷上线时, 缓存工艺规程
|
|
||||||
// BeanFactory.getBean(RedisCacheManager.class).setCoilSetup(form.getPlanId());
|
|
||||||
WebSocketUtil.sendSignalMsg(form);
|
WebSocketUtil.sendSignalMsg(form);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -66,8 +65,6 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
|||||||
@Override
|
@Override
|
||||||
public void operate(L1OperateMatForm form) {
|
public void operate(L1OperateMatForm form) {
|
||||||
PRODUCT.syncPlanStatus(form.getPlanId());
|
PRODUCT.syncPlanStatus(form.getPlanId());
|
||||||
// 删除工艺规程
|
|
||||||
BeanFactory.getBean(RedisCacheManager.class).delCoilSetup(form.getEntryMatId());
|
|
||||||
WebSocketUtil.sendSignalMsg(form);
|
WebSocketUtil.sendSignalMsg(form);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -78,7 +75,7 @@ public enum L1OperateMatEnum implements IEnum<String>, IOperateMat<L1OperateMatF
|
|||||||
CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);
|
CrmPdiPlanService planClient = BeanFactory.getBean(CrmPdiPlanService.class);
|
||||||
CrmPdiPlanVO plan = planClient.getByCoilIdAndOperId(form.getEntryMatId());
|
CrmPdiPlanVO plan = planClient.getByCoilIdAndOperId(form.getEntryMatId());
|
||||||
Assert.notNull(plan, "计划[{}]不存在", plan.getId());
|
Assert.notNull(plan, "计划[{}]不存在", plan.getId());
|
||||||
|
Assert.isTrue(status.contains(plan.getStatus()), "当前状态[{}]不支持甩尾", plan.getStatus());
|
||||||
MatmapUtil.clearMatmap(form.getPorIdx());
|
MatmapUtil.clearMatmap(form.getPorIdx());
|
||||||
WebSocketUtil.sendSignalMsg(form);
|
WebSocketUtil.sendSignalMsg(form);
|
||||||
WebSocketUtil.sendMatmapMsg();
|
WebSocketUtil.sendMatmapMsg();
|
||||||
|
|||||||
@@ -1,20 +1,15 @@
|
|||||||
package com.fizz.business.constants.enums;
|
package com.fizz.business.constants.enums;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IEnum;
|
import com.baomidou.mybatisplus.annotation.IEnum;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonValue;
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
import com.fizz.business.domain.HalfReturn;
|
import com.fizz.business.domain.HalfReturn;
|
||||||
import com.fizz.business.domain.Segment;
|
|
||||||
import com.fizz.business.dto.CoilHeadDTO;
|
|
||||||
import com.fizz.business.dto.ExitCoilInfoDTO;
|
import com.fizz.business.dto.ExitCoilInfoDTO;
|
||||||
import com.fizz.business.dto.MatmapDTO;
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
import com.fizz.business.form.ChangePlanStatusForm;
|
import com.fizz.business.form.ChangePlanStatusForm;
|
||||||
import com.fizz.business.form.WebOperateMatForm;
|
import com.fizz.business.form.WebOperateMatForm;
|
||||||
import com.fizz.business.mapper.HalfReturnMapper;
|
import com.fizz.business.mapper.HalfReturnMapper;
|
||||||
import com.fizz.business.mapper.SegmentMapper;
|
|
||||||
import com.fizz.business.service.CrmPdiPlanService;
|
import com.fizz.business.service.CrmPdiPlanService;
|
||||||
import com.fizz.business.service.PdoExCoilService;
|
import com.fizz.business.service.PdoExCoilService;
|
||||||
import com.fizz.business.service.TrackService;
|
import com.fizz.business.service.TrackService;
|
||||||
@@ -24,14 +19,16 @@ import com.fizz.business.utils.ErrorDataException;
|
|||||||
import com.fizz.business.utils.MatmapUtil;
|
import com.fizz.business.utils.MatmapUtil;
|
||||||
import com.fizz.business.utils.WebSocketUtil;
|
import com.fizz.business.utils.WebSocketUtil;
|
||||||
import com.fizz.business.vo.CrmPdiPlanVO;
|
import com.fizz.business.vo.CrmPdiPlanVO;
|
||||||
import com.fizz.business.vo.PdiPlanVO;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 钢卷操作
|
* 钢卷操作
|
||||||
@@ -53,7 +50,6 @@ public enum WebOperateMatEnum implements IEnum<String>, IOperateMat<WebOperateMa
|
|||||||
if (MatmapUtil.already(porCoil)) {
|
if (MatmapUtil.already(porCoil)) {
|
||||||
|
|
||||||
ONLINE.syncPlanStatus(form.getPlanId());
|
ONLINE.syncPlanStatus(form.getPlanId());
|
||||||
ONLINE.replaceVirtualPlan(form, porCoil);
|
|
||||||
WebSocketUtil.sendSignalMsg(form, true);
|
WebSocketUtil.sendSignalMsg(form, true);
|
||||||
// 如果开卷机和焊机的钢卷相同,则将计划状态变更为生产中
|
// 如果开卷机和焊机的钢卷相同,则将计划状态变更为生产中
|
||||||
MatmapDTO welderCoil = MatmapUtil.getMatmap(DeviceEnum.WELDER.getIdx());
|
MatmapDTO welderCoil = MatmapUtil.getMatmap(DeviceEnum.WELDER.getIdx());
|
||||||
@@ -250,52 +246,4 @@ public enum WebOperateMatEnum implements IEnum<String>, IOperateMat<WebOperateMa
|
|||||||
WebSocketUtil.sendMatmapMsg();
|
WebSocketUtil.sendMatmapMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceVirtualPlan(WebOperateMatForm form, MatmapDTO porCoil) {
|
|
||||||
|
|
||||||
// 更新matmap
|
|
||||||
List<MatmapDTO> matmapList = MatmapUtil.getMatmapList();
|
|
||||||
matmapList.forEach(matmap -> {
|
|
||||||
if (Objects.equals(matmap.getMatId(), porCoil.getMatId())) {
|
|
||||||
MatmapUtil.setMatmap(matmap.getPosIdx(), form.getEntryMatId(), form.getPlanId(), form.getPlanNo());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
RedisCacheManager redisCacheManager = BeanFactory.getBean(RedisCacheManager.class);
|
|
||||||
// 更新headList
|
|
||||||
List<CoilHeadDTO> headList = redisCacheManager.getHeadList();
|
|
||||||
headList.forEach(head -> {
|
|
||||||
if (Objects.equals(head.getMatId(), porCoil.getMatId())) {
|
|
||||||
head.setMatId(form.getEntryMatId());
|
|
||||||
head.setPlanNo(form.getPlanNo());
|
|
||||||
head.setPlanId(form.getPlanId());
|
|
||||||
head.setPorIdx(form.getPorIdx());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
redisCacheManager.setHeadList(headList);
|
|
||||||
// 更新prevHead
|
|
||||||
CoilHeadDTO prevHead = redisCacheManager.getPrevHead();
|
|
||||||
if (Objects.nonNull(prevHead) && Objects.equals(prevHead.getMatId(), porCoil.getMatId())) {
|
|
||||||
prevHead.setMatId(form.getEntryMatId());
|
|
||||||
prevHead.setPlanNo(form.getPlanNo());
|
|
||||||
prevHead.setPlanId(form.getPlanId());
|
|
||||||
prevHead.setPorIdx(form.getPorIdx());
|
|
||||||
redisCacheManager.setPrevHead(prevHead);
|
|
||||||
}
|
|
||||||
// 更新mergeHead
|
|
||||||
CoilHeadDTO mergeHead = redisCacheManager.getMergeHead();
|
|
||||||
if (Objects.nonNull(mergeHead) && Objects.equals(mergeHead.getMatId(), porCoil.getMatId())) {
|
|
||||||
mergeHead.setMatId(form.getEntryMatId());
|
|
||||||
mergeHead.setPlanNo(form.getPlanNo());
|
|
||||||
mergeHead.setPlanId(form.getPlanId());
|
|
||||||
prevHead.setPorIdx(form.getPorIdx());
|
|
||||||
redisCacheManager.setMergeHead(mergeHead);
|
|
||||||
}
|
|
||||||
// 更新segment
|
|
||||||
SegmentMapper segmentMapper = BeanFactory.getBean(SegmentMapper.class);
|
|
||||||
LambdaUpdateWrapper<Segment> updateWrapper = new LambdaUpdateWrapper<>();
|
|
||||||
updateWrapper.eq(Segment::getEntryMatId, porCoil.getMatId());
|
|
||||||
updateWrapper.eq(Segment::getPlanId, porCoil.getPlanId());
|
|
||||||
updateWrapper.set(Segment::getEntryMatId, form.getEntryMatId());
|
|
||||||
updateWrapper.set(Segment::getPlanId, form.getPlanId());
|
|
||||||
segmentMapper.update(new Segment(), updateWrapper);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ public class CrmPdoExcoilController {
|
|||||||
@Resource
|
@Resource
|
||||||
private CrmPdoExcoilService crmPdoExcoilService;
|
private CrmPdoExcoilService crmPdoExcoilService;
|
||||||
|
|
||||||
@GetMapping("/get/{excoilid}/{operid}")
|
@GetMapping("/get/{excoilid}")
|
||||||
@Operation(summary ="查询实绩")
|
@Operation(summary ="查询实绩")
|
||||||
public R<CrmPdoExcoil> getByExcoilIdAndOperId(@PathVariable String excoilid, @PathVariable Integer operid) {
|
public R<CrmPdoExcoil> getByExcoilId(@PathVariable String excoilid) {
|
||||||
return R.ok(crmPdoExcoilService.getByExcoilIdAndOperId(excoilid, operid));
|
return R.ok(crmPdoExcoilService.getByExcoilId(excoilid));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.fizz.business.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fizz.business.service.CrmPdoExcoilService;
|
||||||
|
import com.fizz.business.vo.ReportDetailVO;
|
||||||
|
import com.fizz.business.vo.ReportSummaryVO;
|
||||||
|
import com.ruoyi.common.annotation.Anonymous;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/report")
|
||||||
|
@Tag(name= "报表接口",description = "报表接口")
|
||||||
|
@Anonymous
|
||||||
|
public class ReportController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmPdoExcoilService crmPdoExcoilService;
|
||||||
|
|
||||||
|
@GetMapping("/summary")
|
||||||
|
@Operation(summary = "生产实绩报表-汇总信息查询")
|
||||||
|
public ReportSummaryVO getReportSummary(
|
||||||
|
@RequestParam(required = false) String groupNo,
|
||||||
|
@RequestParam(required = false) String shiftNo,
|
||||||
|
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
|
||||||
|
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime
|
||||||
|
) {
|
||||||
|
return crmPdoExcoilService.getReportSummary(groupNo, shiftNo, startTime, endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/details")
|
||||||
|
@Operation(summary = "生产实绩报表-产出明细查询")
|
||||||
|
public List<ReportDetailVO> getReportDetails(
|
||||||
|
@RequestParam(required = false) String groupNo,
|
||||||
|
@RequestParam(required = false) String shiftNo,
|
||||||
|
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
|
||||||
|
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime
|
||||||
|
) {
|
||||||
|
return crmPdoExcoilService.getReportDetails(groupNo, shiftNo, startTime, endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ public class AppMeasureEntryMessage extends OpcMessage {
|
|||||||
@Schema(description = "钢带位置 (m),0 表示头部在参考点 (Welder)")
|
@Schema(description = "钢带位置 (m),0 表示头部在参考点 (Welder)")
|
||||||
private BigDecimal stripLocation;
|
private BigDecimal stripLocation;
|
||||||
|
|
||||||
@Schema(description = "支付卷号,1 或 2")
|
@Schema(description = "开卷机号,1 或 2")
|
||||||
private Integer payOffReelNumber;
|
private Integer payOffReelNumber;
|
||||||
|
|
||||||
@Schema(description = "钢带张力 POR – BR1 (daN)")
|
@Schema(description = "钢带张力 POR – BR1 (daN)")
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ public class AppMeasureExitMessage extends OpcMessage {
|
|||||||
@Schema(description = "钢带张力 BR8 – BR9 (daN)")
|
@Schema(description = "钢带张力 BR8 – BR9 (daN)")
|
||||||
private BigDecimal tensionBr8Br9;
|
private BigDecimal tensionBr8Br9;
|
||||||
|
|
||||||
@Schema(description = "入口活套位置(m)")
|
@Schema(description = "出口活套位置(m)")
|
||||||
private BigDecimal cxlLength;
|
private BigDecimal cxlLength;
|
||||||
|
|
||||||
@Schema(description = "入口活套百分比(m)")
|
@Schema(description = "出口活套百分比(m)")
|
||||||
private BigDecimal cxlCapacity;
|
private BigDecimal cxlCapacity;
|
||||||
|
|
||||||
@Schema(description = "入口活套张力(m)")
|
@Schema(description = "出口活套张力(m)")
|
||||||
private BigDecimal tensionCxl ;
|
private BigDecimal tensionCxl ;
|
||||||
|
|
||||||
@Schema(description = "涂油标志 (0=no, 1=yes)")
|
@Schema(description = "涂油标志 (0=no, 1=yes)")
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
package com.fizz.business.domain.msg;
|
package com.fizz.business.domain.msg;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
public class AppMeasureMessage extends OpcMessage {
|
public class AppMeasureMessage extends OpcMessage {
|
||||||
|
|
||||||
AppMeasureEntryMessage appMeasureEntryMessage;
|
AppMeasureEntryMessage appMeasureEntryMessage;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.fizz.business.domain.msg;
|
package com.fizz.business.domain.msg;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fizz.business.constants.enums.ExitCutTypeEnum;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@@ -16,7 +17,7 @@ public class ExitCutMessage extends OpcMessage {
|
|||||||
private Integer counter;
|
private Integer counter;
|
||||||
|
|
||||||
@Schema(description = "剪切类型:0=split, 1=weldSeam, 2=stripBreak")
|
@Schema(description = "剪切类型:0=split, 1=weldSeam, 2=stripBreak")
|
||||||
private Integer cutType;
|
private ExitCutTypeEnum cutType;
|
||||||
|
|
||||||
@Schema(description = "剪切时卷取长度 (m)")
|
@Schema(description = "剪切时卷取长度 (m)")
|
||||||
private BigDecimal cutLength;
|
private BigDecimal cutLength;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ public class ExitMovementMessage extends OpcMessage {
|
|||||||
private Integer counter;
|
private Integer counter;
|
||||||
|
|
||||||
@Schema(description = "Material Place Source")
|
@Schema(description = "Material Place Source")
|
||||||
private Integer materialPlaceSource;
|
private Integer exSrc;
|
||||||
|
|
||||||
@Schema(description = "Material Place Destination")
|
@Schema(description = "Material Place Destination")
|
||||||
private Integer materialPlaceDestination;
|
private Integer exDesc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ public class ExitCoilInfoDTO implements Serializable {
|
|||||||
private double startPos;
|
private double startPos;
|
||||||
private double endPos;
|
private double endPos;
|
||||||
private double exitCutLength;
|
private double exitCutLength;
|
||||||
|
private double outerDiameter;
|
||||||
private String entryMatId;
|
private String entryMatId;
|
||||||
private String exitMatId;
|
private String exitMatId;
|
||||||
private boolean separateFlag;
|
private boolean separateFlag;
|
||||||
|
|||||||
@@ -1,17 +1,31 @@
|
|||||||
package com.fizz.business.dto;
|
package com.fizz.business.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@Getter
|
@Data
|
||||||
@Setter
|
|
||||||
public class SegValue implements Serializable {
|
public class SegValue implements Serializable {
|
||||||
private double max;
|
private BigDecimal max;
|
||||||
private double min;
|
private BigDecimal min;
|
||||||
private double avg;
|
private BigDecimal avg;
|
||||||
private double std;
|
private BigDecimal std;
|
||||||
private int cnt;
|
private int cnt;
|
||||||
private double sum;
|
private BigDecimal sum;
|
||||||
|
|
||||||
|
public void add(BigDecimal value) {
|
||||||
|
this.sum = this.sum.add(value);
|
||||||
|
this.cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getAverage() {
|
||||||
|
if (cnt == 0) {
|
||||||
|
return BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
return sum.divide(new BigDecimal(cnt), 2, BigDecimal.ROUND_HALF_UP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,57 @@
|
|||||||
package com.fizz.business.dto;
|
package com.fizz.business.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class SegmentDTO {
|
@TableName("cpl_segment_total")
|
||||||
|
public class SegmentDTO implements Serializable {
|
||||||
|
|
||||||
private boolean first;
|
@TableId(type = IdType.AUTO)
|
||||||
private Long planId;
|
private Long id;
|
||||||
private String planNo;
|
|
||||||
private String coilID;
|
@TableField("en_coil_id")
|
||||||
private String enCoilID;
|
private String enCoilID;
|
||||||
private String exCoilID;
|
|
||||||
//MATID_Type matId;
|
@TableField("pickling_count")
|
||||||
private int segNo;
|
private Integer picklingCount;
|
||||||
private double segLen;
|
|
||||||
private double startPos;//位于带钢的起始位置
|
@TableField("seg_no")
|
||||||
private double endPos;
|
private Integer segNo;
|
||||||
private double headPos;//位于全线的位置
|
|
||||||
private double tailPos;
|
// 以下字段用于业务逻辑,不存入数据库
|
||||||
|
@TableField(exist = false)
|
||||||
|
private BigDecimal headPos;
|
||||||
|
@TableField(exist = false)
|
||||||
|
private BigDecimal tailPos;
|
||||||
|
|
||||||
|
// 以下字段存入数据库
|
||||||
|
@TableField("start_pos")
|
||||||
|
private BigDecimal startPos;
|
||||||
|
@TableField("end_pos")
|
||||||
|
private BigDecimal endPos;
|
||||||
|
@TableField("seg_len")
|
||||||
|
private BigDecimal segLen;
|
||||||
|
@TableField("total_values_json")
|
||||||
|
private String totalValuesJson;
|
||||||
|
|
||||||
|
// 以下 Map 用于业务逻辑,不存入数据库
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Map<String, SegValue> totalValues = new ConcurrentHashMap<>();
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Map<String, SegValue> L3values = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// 两个未使用的字段,可以根据需要保留或移除
|
||||||
|
@TableField(exist = false)
|
||||||
private int headPosNum;
|
private int headPosNum;
|
||||||
|
@TableField(exist = false)
|
||||||
private int tailPosNum;
|
private int tailPosNum;
|
||||||
private Map<String, SegValue> segValMap;
|
}
|
||||||
}
|
|
||||||
@@ -2,8 +2,30 @@ package com.fizz.business.mapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.fizz.business.domain.CrmPdoExcoil;
|
import com.fizz.business.domain.CrmPdoExcoil;
|
||||||
|
import com.fizz.business.vo.ReportDetailVO;
|
||||||
|
import com.fizz.business.vo.ReportSummaryVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface CrmPdoExcoilMapper extends BaseMapper<CrmPdoExcoil> {
|
public interface CrmPdoExcoilMapper extends BaseMapper<CrmPdoExcoil> {
|
||||||
|
|
||||||
|
|
||||||
|
ReportSummaryVO getReportSummary(
|
||||||
|
@Param("groupNo") String groupNo,
|
||||||
|
@Param("shiftNo") String shiftNo,
|
||||||
|
@Param("startTime") LocalDateTime startTime,
|
||||||
|
@Param("endTime") LocalDateTime endTime
|
||||||
|
);
|
||||||
|
|
||||||
|
List<ReportDetailVO> getReportDetails(
|
||||||
|
@Param("groupNo") String groupNo,
|
||||||
|
@Param("shiftNo") String shiftNo,
|
||||||
|
@Param("startTime") LocalDateTime startTime,
|
||||||
|
@Param("endTime") LocalDateTime endTime
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.fizz.business.mapper;
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.fizz.business.domain.PdoStripvalue;
|
import com.fizz.business.domain.PdoStripvalue;
|
||||||
import com.fizz.business.domain.Segment;
|
import com.fizz.business.domain.Segment;
|
||||||
|
import com.fizz.business.dto.SegmentDTO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ import org.apache.ibatis.annotations.Param;
|
|||||||
* @since 2023-05-17
|
* @since 2023-05-17
|
||||||
*/
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface SegmentMapper extends BaseMapper<Segment> {
|
public interface SegmentMapper extends BaseMapper<SegmentDTO> {
|
||||||
|
|
||||||
PdoStripvalue getStripValue(@Param("entryMatId") String entryMatId, @Param("startPos") double startPos, @Param("endPos") double endPos);
|
PdoStripvalue getStripValue(@Param("entryMatId") String entryMatId, @Param("startPos") double startPos, @Param("endPos") double endPos);
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,15 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
import com.fizz.business.domain.CrmPdoExcoil;
|
import com.fizz.business.domain.CrmPdoExcoil;
|
||||||
import com.fizz.business.domain.PdoExcoil;
|
import com.fizz.business.domain.PdoExcoil;
|
||||||
import com.fizz.business.form.CrmPdoExcoilForm;
|
import com.fizz.business.form.CrmPdoExcoilForm;
|
||||||
|
import com.fizz.business.vo.ReportDetailVO;
|
||||||
|
import com.fizz.business.vo.ReportSummaryVO;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface CrmPdoExcoilService extends IService<CrmPdoExcoil> {
|
public interface CrmPdoExcoilService extends IService<CrmPdoExcoil> {
|
||||||
CrmPdoExcoil getByExcoilIdAndOperId(String excoilid, Integer operid);
|
CrmPdoExcoil getByExcoilId(String excoilid);
|
||||||
|
|
||||||
boolean addCrmPdoExcoil(CrmPdoExcoil crmPdoExcoil);
|
boolean addCrmPdoExcoil(CrmPdoExcoil crmPdoExcoil);
|
||||||
|
|
||||||
@@ -20,5 +24,11 @@ public interface CrmPdoExcoilService extends IService<CrmPdoExcoil> {
|
|||||||
List<CrmPdoExcoil> listAll(CrmPdoExcoilForm form);
|
List<CrmPdoExcoil> listAll(CrmPdoExcoilForm form);
|
||||||
|
|
||||||
Long getNumber(String matId,String planId,Integer subNumber);
|
Long getNumber(String matId,String planId,Integer subNumber);
|
||||||
|
|
||||||
|
ReportSummaryVO getReportSummary(String groupNo, String shiftNo, LocalDateTime startTime, LocalDateTime endTime);
|
||||||
|
|
||||||
|
List<ReportDetailVO> getReportDetails(String groupNo, String shiftNo, LocalDateTime startTime, LocalDateTime endTime);
|
||||||
|
|
||||||
|
void updateExitCoilActualWeight(String exitMatId, BigDecimal weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
package com.fizz.business.service.client;
|
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
|
||||||
import cn.hutool.core.lang.Pair;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.fizz.business.constants.enums.LimitItemCode;
|
|
||||||
import com.fizz.business.domain.DeviceDefine;
|
|
||||||
import com.fizz.business.dto.PointConfigDTO;
|
|
||||||
import com.fizz.business.mapper.DeviceDefineMapper;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.DependsOn;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 本地缓存管理
|
|
||||||
*
|
|
||||||
* @author chenhao
|
|
||||||
* @date 2023/05/15
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class LocalCacheManager {
|
|
||||||
|
|
||||||
private static DeviceDefineMapper deviceDefineMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public void setDeviceDefineMapper(DeviceDefineMapper deviceDefineMapper) {
|
|
||||||
LocalCacheManager.deviceDefineMapper = deviceDefineMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LinkedHashMap<String, DeviceDefine> DEVICE_DEFINE_MAP = Maps.newLinkedHashMap();
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public static void init() {
|
|
||||||
DEVICE_DEFINE_MAP = getDeviceDefine();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static LinkedHashMap<String, DeviceDefine> getDeviceDefine() {
|
|
||||||
List<DeviceDefine> list = deviceDefineMapper.selectList(new LambdaQueryWrapper<DeviceDefine>().orderByAsc(DeviceDefine::getPosIdx));
|
|
||||||
return list.stream().collect(Collectors.toMap(DeviceDefine::getPositionNameEn, it -> it, (k1, k2) -> k1, LinkedHashMap::new));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -116,14 +116,14 @@ public class RedisCacheManager {
|
|||||||
if (segmentList.isEmpty()) {
|
if (segmentList.isEmpty()) {
|
||||||
segmentRedisTemplate.opsForList().rightPush(COIL_SEG_LIST_KEY, segment);
|
segmentRedisTemplate.opsForList().rightPush(COIL_SEG_LIST_KEY, segment);
|
||||||
log.info("create new segment, coilId=[{}], segNo={}, startPos={}, endPos={}, segLen={}",
|
log.info("create new segment, coilId=[{}], segNo={}, startPos={}, endPos={}, segLen={}",
|
||||||
segment.getCoilID(), segment.getSegNo(), segment.getStartPos(), segment.getEndPos(), segment.getSegLen());
|
segment.getEnCoilID(), segment.getSegNo(), segment.getStartPos(), segment.getEndPos(), segment.getSegLen());
|
||||||
} else {
|
} else {
|
||||||
Map<String, String> exists = segmentList.stream().collect(Collectors.toMap(s -> s.getCoilID() + "-" + s.getSegNo() + "-" + s.getPlanId(), s -> s.getCoilID() + s.getSegNo() + s.getPlanId(), (k1, k2) -> k1));
|
Map<String, String> exists = segmentList.stream().collect(Collectors.toMap(s -> s.getEnCoilID() + "-" + s.getSegNo(), s -> s.getEnCoilID() + s.getSegNo() , (k1, k2) -> k1));
|
||||||
String key = segment.getCoilID() + "-" + segment.getSegNo() + "-" + segment.getPlanId();
|
String key = segment.getEnCoilID() + "-" + segment.getSegNo() ;
|
||||||
if (!exists.containsKey(key)) {
|
if (!exists.containsKey(key)) {
|
||||||
segmentRedisTemplate.opsForList().rightPush(COIL_SEG_LIST_KEY, segment);
|
segmentRedisTemplate.opsForList().rightPush(COIL_SEG_LIST_KEY, segment);
|
||||||
log.info("create new segment, coilId=[{}], segNo={}, startPos={}, endPos={}, segLen={}",
|
log.info("create new segment, coilId=[{}], segNo={}, startPos={}, endPos={}, segLen={}",
|
||||||
segment.getCoilID(), segment.getSegNo(), segment.getStartPos(), segment.getEndPos(), segment.getSegLen());
|
segment.getEnCoilID(), segment.getSegNo(), segment.getStartPos(), segment.getEndPos(), segment.getSegLen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,45 @@
|
|||||||
package com.fizz.business.service.hanle;
|
package com.fizz.business.service.hanle;
|
||||||
|
|
||||||
import com.fizz.business.anno.OpcMessageHandlerType;
|
import com.fizz.business.anno.OpcMessageHandlerType;
|
||||||
|
import com.fizz.business.constants.enums.DeviceEnum;
|
||||||
import com.fizz.business.constants.enums.OpcMessageType;
|
import com.fizz.business.constants.enums.OpcMessageType;
|
||||||
import com.fizz.business.domain.msg.AppMeasureExitMessage;
|
import com.fizz.business.domain.msg.*;
|
||||||
import com.fizz.business.domain.msg.AppMeasureMessage;
|
|
||||||
import com.fizz.business.service.OpcMessageHandler;
|
import com.fizz.business.service.OpcMessageHandler;
|
||||||
|
import com.fizz.business.service.strip.SegmentTrackerService;
|
||||||
|
import com.fizz.business.service.strip.StripPositionService;
|
||||||
|
import com.fizz.business.utils.WebSocketUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@OpcMessageHandlerType(OpcMessageType.APP_MEASURE)
|
@OpcMessageHandlerType(OpcMessageType.APP_MEASURE)
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class AppMeasureHandler implements OpcMessageHandler<AppMeasureMessage> {
|
public class AppMeasureHandler implements OpcMessageHandler<AppMeasureMessage> {
|
||||||
|
|
||||||
|
private final SegmentTrackerService tracker;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(AppMeasureMessage message) {
|
public void handle(AppMeasureMessage message) {
|
||||||
// 处理出口段测量逻辑
|
if (message == null) return;
|
||||||
System.out.println("处理 APP_MEASURE_EXIT 消息: " + message);
|
|
||||||
|
AppMeasureEntryMessage entry = message.getAppMeasureEntryMessage();
|
||||||
|
AppMeasureFurnaceMessage furnace = message.getAppMeasureFurnaceMessage();
|
||||||
|
AppMeasureCoatMessage coat = message.getAppMeasureCoatMessage();
|
||||||
|
AppMeasureExitMessage exit = message.getAppMeasureExitMessage();
|
||||||
|
|
||||||
|
WebSocketUtil.sendMeasureMsg(message);
|
||||||
|
|
||||||
|
// 2) extract key fields
|
||||||
|
String coilId = entry == null ? "UNKNOWN" : entry.getEntryCoilId();
|
||||||
|
BigDecimal lengthAtWelder = entry == null || entry.getStripLocation() == null ? BigDecimal.ZERO : entry.getStripLocation();
|
||||||
|
|
||||||
|
// 3) delegate core processing to tracker
|
||||||
|
tracker.handleMeasure(coilId, lengthAtWelder, entry, furnace, coat, exit);
|
||||||
|
|
||||||
|
// 调用新的方法来跟踪钢卷头部位置,并处理快照和 matmap 更新
|
||||||
|
// 使用焊机长度作为最接近的钢卷头部位置
|
||||||
|
tracker.trackCoilHeadPosition(coilId, lengthAtWelder, entry, exit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,10 +5,12 @@ import com.fizz.business.constants.enums.L1OperateMatEnum;
|
|||||||
import com.fizz.business.constants.enums.OpcMessageType;
|
import com.fizz.business.constants.enums.OpcMessageType;
|
||||||
import com.fizz.business.domain.CrmPdiPlan;
|
import com.fizz.business.domain.CrmPdiPlan;
|
||||||
import com.fizz.business.domain.msg.EntryMovementMessage;
|
import com.fizz.business.domain.msg.EntryMovementMessage;
|
||||||
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
import com.fizz.business.form.L1OperateMatForm;
|
import com.fizz.business.form.L1OperateMatForm;
|
||||||
import com.fizz.business.service.CrmPdiPlanService;
|
import com.fizz.business.service.CrmPdiPlanService;
|
||||||
import com.fizz.business.service.OpcMessageHandler;
|
import com.fizz.business.service.OpcMessageHandler;
|
||||||
import com.fizz.business.service.TrackService;
|
import com.fizz.business.service.TrackService;
|
||||||
|
import com.fizz.business.utils.MatmapUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -52,6 +54,17 @@ public class EntryMovementHandler implements OpcMessageHandler<EntryMovementMess
|
|||||||
} else {
|
} else {
|
||||||
log.error("未找到可上卷的钢卷计划!");
|
log.error("未找到可上卷的钢卷计划!");
|
||||||
}
|
}
|
||||||
|
}else if (action.contains("甩尾")){
|
||||||
|
|
||||||
|
MatmapDTO matmap = MatmapUtil.getMatmap(src);
|
||||||
|
|
||||||
|
log.info("获取到甩尾信息: " + matmap.getMatId());
|
||||||
|
trackService.l1OperateMat(L1OperateMatForm.builder()
|
||||||
|
.entryMatId(matmap.getMatId())
|
||||||
|
.operation(L1OperateMatEnum.PAY_OVER)
|
||||||
|
.planId(matmap.getPlanId())
|
||||||
|
.porIdx(src)
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.error("未识别的组合: SRC=" + src + ", DES=" + des);
|
log.error("未识别的组合: SRC=" + src + ", DES=" + des);
|
||||||
|
|||||||
@@ -1,18 +1,61 @@
|
|||||||
package com.fizz.business.service.hanle;
|
package com.fizz.business.service.hanle;
|
||||||
|
|
||||||
import com.fizz.business.anno.OpcMessageHandlerType;
|
import com.fizz.business.anno.OpcMessageHandlerType;
|
||||||
|
import com.fizz.business.constants.enums.L1OperateMatEnum;
|
||||||
import com.fizz.business.constants.enums.OpcMessageType;
|
import com.fizz.business.constants.enums.OpcMessageType;
|
||||||
import com.fizz.business.domain.msg.ExitCutMessage;
|
import com.fizz.business.domain.msg.ExitCutMessage;
|
||||||
|
import com.fizz.business.dto.ExitCoilInfoDTO;
|
||||||
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
|
import com.fizz.business.form.L1OperateMatForm;
|
||||||
import com.fizz.business.service.OpcMessageHandler;
|
import com.fizz.business.service.OpcMessageHandler;
|
||||||
|
import com.fizz.business.service.PdoExCoilService;
|
||||||
|
import com.fizz.business.service.TrackService;
|
||||||
|
import com.fizz.business.utils.MatmapUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import static com.fizz.business.constants.enums.DeviceEnum.TR;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
@OpcMessageHandlerType(OpcMessageType.EXIT_CUT)
|
@OpcMessageHandlerType(OpcMessageType.EXIT_CUT)
|
||||||
public class ExitCutHandler implements OpcMessageHandler<ExitCutMessage> {
|
public class ExitCutHandler implements OpcMessageHandler<ExitCutMessage> {
|
||||||
|
|
||||||
|
// 注入 PdoExCoilService
|
||||||
|
private final PdoExCoilService pdoExCoilService;
|
||||||
|
private final TrackService trackService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(ExitCutMessage message) {
|
public void handle(ExitCutMessage message) {
|
||||||
// 出口剪切逻辑处理
|
// 1. 获取卷取机 (TR) 上的物料信息
|
||||||
System.out.println("处理 EXIT_CUT 消息: " + message);
|
MatmapDTO trMatmap = MatmapUtil.getMatmap(TR.getIdx());
|
||||||
|
|
||||||
|
if (trMatmap == null) {
|
||||||
|
log.error("卷取机s.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 根据剪切类型,生成产出卷信息
|
||||||
|
ExitCoilInfoDTO exitCoilInfo = pdoExCoilService.genExitCoilInfo(trMatmap, message.getCutType());
|
||||||
|
|
||||||
|
// 3. 补充 ExitCutMessage 中的长度和外径信息
|
||||||
|
exitCoilInfo.setExitCutLength(message.getCutLength().doubleValue());
|
||||||
|
exitCoilInfo.setOuterDiameter(message.getOuterDiameter().doubleValue());
|
||||||
|
|
||||||
|
// 4. 调用服务进行产出卷的持久化
|
||||||
|
pdoExCoilService.saveExCoil(exitCoilInfo);
|
||||||
|
|
||||||
|
if (exitCoilInfo.isLastFlag()) {
|
||||||
|
trackService.l1OperateMat(L1OperateMatForm.builder()
|
||||||
|
.trIdx(TR.getIdx())
|
||||||
|
.entryMatId(trMatmap.getMatId())
|
||||||
|
.planId(trMatmap.getPlanId())
|
||||||
|
.operation(L1OperateMatEnum.PRODUCT)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("成功处理 EXIT_CUT 消息,已保存成品卷: " + exitCoilInfo.getExitMatId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,34 @@ package com.fizz.business.service.hanle;
|
|||||||
import com.fizz.business.anno.OpcMessageHandlerType;
|
import com.fizz.business.anno.OpcMessageHandlerType;
|
||||||
import com.fizz.business.constants.enums.OpcMessageType;
|
import com.fizz.business.constants.enums.OpcMessageType;
|
||||||
import com.fizz.business.domain.msg.ExitMeasureMessage;
|
import com.fizz.business.domain.msg.ExitMeasureMessage;
|
||||||
|
import com.fizz.business.service.CrmPdoExcoilService;
|
||||||
import com.fizz.business.service.OpcMessageHandler;
|
import com.fizz.business.service.OpcMessageHandler;
|
||||||
|
import com.fizz.business.utils.MatmapUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import static com.fizz.business.constants.enums.DeviceEnum.TR;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@OpcMessageHandlerType(OpcMessageType.EXIT_MEASURE)
|
@OpcMessageHandlerType(OpcMessageType.EXIT_MEASURE)
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ExitMeasureHandler implements OpcMessageHandler<ExitMeasureMessage> {
|
public class ExitMeasureHandler implements OpcMessageHandler<ExitMeasureMessage> {
|
||||||
|
|
||||||
|
private final CrmPdoExcoilService crmPdoExcoilService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(ExitMeasureMessage message) {
|
public void handle(ExitMeasureMessage message) {
|
||||||
// 出口称重逻辑处理
|
|
||||||
System.out.println("处理 EXIT_MEASURE 消息: " + message);
|
System.out.println("处理 EXIT_MEASURE 消息: " + message);
|
||||||
|
|
||||||
|
// 1. 获取卷取机 (TR) 上的成品卷号
|
||||||
|
String exitMatId = MatmapUtil.getMatId(TR.getIdx());
|
||||||
|
|
||||||
|
if (exitMatId == null) {
|
||||||
|
System.err.println("TR device has no coil. Cannot process ExitMeasureMessage.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 调用服务层更新成品卷的实际重量
|
||||||
|
crmPdoExcoilService.updateExitCoilActualWeight(exitMatId, message.getWeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,46 @@
|
|||||||
package com.fizz.business.service.hanle;
|
package com.fizz.business.service.hanle;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.fizz.business.anno.OpcMessageHandlerType;
|
import com.fizz.business.anno.OpcMessageHandlerType;
|
||||||
import com.fizz.business.constants.enums.OpcMessageType;
|
import com.fizz.business.constants.enums.OpcMessageType;
|
||||||
import com.fizz.business.domain.msg.ExitMovementMessage;
|
import com.fizz.business.domain.msg.ExitMovementMessage;
|
||||||
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
import com.fizz.business.service.OpcMessageHandler;
|
import com.fizz.business.service.OpcMessageHandler;
|
||||||
|
import com.fizz.business.utils.MatmapUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Slf4j
|
||||||
@OpcMessageHandlerType(OpcMessageType.EXIT_MOVEMENT)
|
@OpcMessageHandlerType(OpcMessageType.EXIT_MOVEMENT)
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class ExitMovementHandler implements OpcMessageHandler<ExitMovementMessage> {
|
public class ExitMovementHandler implements OpcMessageHandler<ExitMovementMessage> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(ExitMovementMessage message) {
|
public void handle(ExitMovementMessage message) {
|
||||||
// 出口移动逻辑处理
|
System.out.printf("处理 EXIT_MOVEMENT 消息: %d -> %d%n", message.getExSrc(), message.getExDesc());
|
||||||
System.out.println("处理 EXIT_MOVEMENT 消息: " + message);
|
|
||||||
|
// 1. 获取源位置的物料信息
|
||||||
|
int srcIndex = message.getExSrc() -1 ;
|
||||||
|
MatmapDTO srcMatmap = MatmapUtil.getMatmap(srcIndex);
|
||||||
|
|
||||||
|
if (ObjectUtil.isNull(srcMatmap) || ObjectUtil.isNull(srcMatmap.getMatId())) {
|
||||||
|
log.error("源位置 {} 没有物料信息,跳过移动处理。", srcIndex);
|
||||||
|
// 如果源位置没有物料,则可能是一次无效的移动,直接返回
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 清空源位置的物料信息
|
||||||
|
MatmapUtil.clearMatmap(srcIndex);
|
||||||
|
log.info("成功清空源位置 {} 的物料信息。{}", srcIndex,srcMatmap.getMatId());
|
||||||
|
|
||||||
|
// 3. 将物料信息设置到目标位置
|
||||||
|
int destIndex = message.getExDesc() - 1;
|
||||||
|
MatmapUtil.setMatmap(destIndex, srcMatmap.getMatId(), srcMatmap.getPlanId(), srcMatmap.getPlanNo());
|
||||||
|
log.info("成功设置目标位置 {} 的物料信息为钢卷 {}", destIndex, srcMatmap.getMatId());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,24 +8,31 @@ import com.fizz.business.domain.PdoExcoil;
|
|||||||
import com.fizz.business.form.CrmPdoExcoilForm;
|
import com.fizz.business.form.CrmPdoExcoilForm;
|
||||||
import com.fizz.business.mapper.CrmPdoExcoilMapper;
|
import com.fizz.business.mapper.CrmPdoExcoilMapper;
|
||||||
import com.fizz.business.service.CrmPdoExcoilService;
|
import com.fizz.business.service.CrmPdoExcoilService;
|
||||||
|
import com.fizz.business.vo.ReportDetailVO;
|
||||||
|
import com.fizz.business.vo.ReportSummaryVO;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class CrmPdoExcoilServiceImpl extends ServiceImpl<CrmPdoExcoilMapper, CrmPdoExcoil> implements CrmPdoExcoilService {
|
public class CrmPdoExcoilServiceImpl extends ServiceImpl<CrmPdoExcoilMapper, CrmPdoExcoil> implements CrmPdoExcoilService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据退出卷ID和操作员ID查询记录
|
* 根据退出卷ID和操作员ID查询记录
|
||||||
*
|
*
|
||||||
* @param excoilid 退出卷ID
|
* @param excoilid 退出卷ID
|
||||||
* @param operid 操作员ID
|
|
||||||
* @return 查询到的CrmPdoExcoil对象
|
* @return 查询到的CrmPdoExcoil对象
|
||||||
*/
|
*/
|
||||||
public CrmPdoExcoil getByExcoilIdAndOperId(String excoilid, Integer operid) {
|
public CrmPdoExcoil getByExcoilId(String excoilid) {
|
||||||
QueryWrapper<CrmPdoExcoil> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<CrmPdoExcoil> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("exit_coilid", excoilid).eq("operid", operid);
|
queryWrapper.eq("exit_coilid", excoilid);
|
||||||
return this.getOne(queryWrapper);
|
return this.getOne(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,5 +105,51 @@ public class CrmPdoExcoilServiceImpl extends ServiceImpl<CrmPdoExcoilMapper, Crm
|
|||||||
return baseMapper.selectCount(queryWrapper);
|
return baseMapper.selectCount(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReportSummaryVO getReportSummary(String groupNo, String shiftNo, LocalDateTime startTime, LocalDateTime endTime) {
|
||||||
|
return baseMapper.getReportSummary(groupNo, shiftNo, startTime, endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ReportDetailVO> getReportDetails(String groupNo, String shiftNo, LocalDateTime startTime, LocalDateTime endTime) {
|
||||||
|
return baseMapper.getReportDetails(groupNo, shiftNo, startTime, endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【新增实现】
|
||||||
|
* 负责更新产出卷的实际重量和状态。
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void updateExitCoilActualWeight(String exitMatId, BigDecimal actualWeight) {
|
||||||
|
// 1. 根据成品卷号查询记录
|
||||||
|
CrmPdoExcoil excoil = this.getByExcoilId(exitMatId);
|
||||||
|
|
||||||
|
if (excoil == null) {
|
||||||
|
log.error("未找到成品卷 {} 的数据库记录,无法更新重量。", exitMatId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查当前状态是否为 "UNWEIGHT" (未称重)
|
||||||
|
// 确保我们只更新未处理过的卷
|
||||||
|
if (Objects.equals(excoil.getStatus(), "UNWEIGHT")) {
|
||||||
|
// 3. 更新实际重量和状态
|
||||||
|
excoil.setActualWeight(actualWeight.doubleValue());
|
||||||
|
excoil.setStatus("COMPLETED"); // 或其他最终状态,如 "WEIGHED"
|
||||||
|
|
||||||
|
// 4. 调用 CRM 服务进行数据库更新
|
||||||
|
boolean success = this.updateCrmPdoExcoil(excoil);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
log.info("成品卷 {} 的实际重量已成功更新为 {} kg,状态变为 {}.",
|
||||||
|
exitMatId, actualWeight, excoil.getStatus());
|
||||||
|
} else {
|
||||||
|
log.error("更新成品卷 {} 失败。", exitMatId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("成品卷 {} 的状态不是 'UNWEIGHT',当前状态为 '{}',跳过重量更新。",
|
||||||
|
exitMatId, excoil.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class PdoExCoilServiceImpl implements PdoExCoilService {
|
|||||||
// 产出实际入库
|
// 产出实际入库
|
||||||
crmPdoExcoilService.addCrmPdoExcoil(pdoExCoilDTO);
|
crmPdoExcoilService.addCrmPdoExcoil(pdoExCoilDTO);
|
||||||
// 打包segment
|
// 打包segment
|
||||||
pdoStripValueService.treatStripValues(exitCoil);
|
// pdoStripValueService.treatStripValues(exitCoil);
|
||||||
return pdoExCoilDTO;
|
return pdoExCoilDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.fizz.business.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fizz.business.dto.SegmentDTO;
|
||||||
|
import com.fizz.business.mapper.SegmentMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SegmentService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SegmentMapper segmentMapper;
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper(); // 用于JSON转换
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存完整的段数据,包含插入和更新逻辑。
|
||||||
|
* 对应 C++ 的 saveTotalSegment() 方法。
|
||||||
|
*
|
||||||
|
* @param segment 待保存的段数据对象
|
||||||
|
*/
|
||||||
|
public void saveTotalSegment(SegmentDTO segment) {
|
||||||
|
if (segment == null || segment.getEnCoilID() == null || segment.getEnCoilID().isEmpty()) {
|
||||||
|
System.err.println("警告: Coil ID 为空,无法保存数据。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 将动态的 Map 数据转换为 JSON 字符串
|
||||||
|
Map<String, BigDecimal> totalValuesAvg = new HashMap<>();
|
||||||
|
segment.getTotalValues().forEach((key, segValue) -> {
|
||||||
|
// 这里将 key 拼接上 "_avg" 以示区分,如果需要也可以不加
|
||||||
|
totalValuesAvg.put(key + "_avg", segValue.getAverage());
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 使用 Jackson ObjectMapper 将 Map 转换为 JSON 字符串
|
||||||
|
String jsonString = objectMapper.writeValueAsString(totalValuesAvg);
|
||||||
|
segment.setTotalValuesJson(jsonString);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
System.err.println("转换 JSON 失败: " + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 先执行删除,再插入,以避免重复数据(与 C++ 逻辑保持一致)
|
||||||
|
QueryWrapper<SegmentDTO> deleteWrapper = new QueryWrapper<>();
|
||||||
|
deleteWrapper.eq("en_coil_id", segment.getEnCoilID())
|
||||||
|
.eq("seg_no", segment.getSegNo());
|
||||||
|
segmentMapper.delete(deleteWrapper);
|
||||||
|
|
||||||
|
// 3. 执行插入操作,MyBatis-Plus 会自动处理 totalValuesJson 字段的保存
|
||||||
|
segmentMapper.insert(segment);
|
||||||
|
|
||||||
|
System.out.println("段数据保存成功。钢卷号: " + segment.getEnCoilID() + ", 段号: " + segment.getSegNo());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,30 +3,23 @@ package com.fizz.business.service.impl;
|
|||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.fizz.business.constants.enums.DeviceEnum;
|
import com.fizz.business.constants.enums.DeviceEnum;
|
||||||
import com.fizz.business.constants.enums.PlanStatusEnum;
|
import com.fizz.business.constants.enums.PlanStatusEnum;
|
||||||
import com.fizz.business.constants.enums.WebOperateMatEnum;
|
import com.fizz.business.constants.enums.WebOperateMatEnum;
|
||||||
import com.fizz.business.domain.DeviceDefine;
|
|
||||||
import com.fizz.business.domain.HalfReturn;
|
|
||||||
import com.fizz.business.dto.CoilHeadDTO;
|
import com.fizz.business.dto.CoilHeadDTO;
|
||||||
import com.fizz.business.dto.CoilPositionDTO;
|
import com.fizz.business.dto.CoilPositionDTO;
|
||||||
import com.fizz.business.dto.MatmapDTO;
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
import com.fizz.business.form.AdjustPosForm;
|
import com.fizz.business.form.AdjustPosForm;
|
||||||
import com.fizz.business.form.L1OperateMatForm;
|
import com.fizz.business.form.L1OperateMatForm;
|
||||||
import com.fizz.business.form.WebOperateMatForm;
|
import com.fizz.business.form.WebOperateMatForm;
|
||||||
import com.fizz.business.mapper.HalfReturnMapper;
|
|
||||||
import com.fizz.business.mapper.SegmentMapper;
|
|
||||||
import com.fizz.business.service.CrmPdiPlanService;
|
import com.fizz.business.service.CrmPdiPlanService;
|
||||||
import com.fizz.business.service.TrackService;
|
import com.fizz.business.service.TrackService;
|
||||||
import com.fizz.business.service.client.LocalCacheManager;
|
|
||||||
import com.fizz.business.service.client.RedisCacheManager;
|
import com.fizz.business.service.client.RedisCacheManager;
|
||||||
import com.fizz.business.utils.CalcUtil;
|
import com.fizz.business.utils.CalcUtil;
|
||||||
import com.fizz.business.utils.CoilMeasUtil;
|
import com.fizz.business.utils.CoilMeasUtil;
|
||||||
import com.fizz.business.utils.MatmapUtil;
|
import com.fizz.business.utils.MatmapUtil;
|
||||||
import com.fizz.business.utils.WebSocketUtil;
|
import com.fizz.business.utils.WebSocketUtil;
|
||||||
import com.fizz.business.vo.CrmPdiPlanVO;
|
import com.fizz.business.vo.CrmPdiPlanVO;
|
||||||
import com.fizz.business.vo.HalfReturnInfoVO;
|
|
||||||
import com.fizz.business.vo.ReturnInfoVO;
|
import com.fizz.business.vo.ReturnInfoVO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -50,8 +43,7 @@ public class TrackServiceImpl implements TrackService {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RedisCacheManager redisCacheManager;
|
RedisCacheManager redisCacheManager;
|
||||||
@Autowired
|
|
||||||
SegmentMapper segmentMapper;
|
|
||||||
@Autowired
|
@Autowired
|
||||||
CrmPdiPlanService crmPdiPlanService;
|
CrmPdiPlanService crmPdiPlanService;
|
||||||
|
|
||||||
@@ -107,10 +99,10 @@ public class TrackServiceImpl implements TrackService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void adjustPosition(AdjustPosForm form) {
|
public void adjustPosition(AdjustPosForm form) {
|
||||||
DeviceDefine targetDevice = LocalCacheManager.DEVICE_DEFINE_MAP.get(form.getTargetPos().name());
|
DeviceEnum targetDevice = DeviceEnum.fromName(form.getTargetPos().name());
|
||||||
Assert.notNull(targetDevice, "目标位置设备不存在");
|
Assert.notNull(targetDevice, "目标位置设备不存在");
|
||||||
|
|
||||||
DeviceDefine currentDevice = LocalCacheManager.DEVICE_DEFINE_MAP.get(form.getCurrentPos().name());
|
DeviceEnum currentDevice = DeviceEnum.fromName(form.getCurrentPos().name());
|
||||||
Assert.notNull(currentDevice, "当前位置设备不存在");
|
Assert.notNull(currentDevice, "当前位置设备不存在");
|
||||||
|
|
||||||
// 更新matmap
|
// 更新matmap
|
||||||
@@ -129,16 +121,16 @@ public class TrackServiceImpl implements TrackService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// 多个卷取机需要跳过1#卷取机
|
// 多个卷取机需要跳过1#卷取机
|
||||||
if (Objects.equals(endPos, DeviceEnum.TR2.getIdx())
|
if (Objects.equals(endPos, DeviceEnum.TR.getIdx())
|
||||||
&& Objects.equals(currPos, DeviceEnum.TR1.getIdx())) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshMatmap(DeviceDefine targetDevice, DeviceDefine currDevice, AdjustPosForm form) {
|
private void refreshMatmap(DeviceEnum targetDevice, DeviceEnum currDevice, AdjustPosForm form) {
|
||||||
Integer targetPosIdx = targetDevice.getPosIdx();
|
Integer targetPosIdx = targetDevice.getIdx();
|
||||||
Integer currPosIdx = currDevice.getPosIdx();
|
Integer currPosIdx = currDevice.getIdx();
|
||||||
MatmapDTO target = MatmapUtil.getMatmap(targetPosIdx);
|
MatmapDTO target = MatmapUtil.getMatmap(targetPosIdx);
|
||||||
MatmapDTO curr = MatmapUtil.getMatmap(currPosIdx);
|
MatmapDTO curr = MatmapUtil.getMatmap(currPosIdx);
|
||||||
if (Objects.equals(curr.getMatId(), target.getMatId())) {
|
if (Objects.equals(curr.getMatId(), target.getMatId())) {
|
||||||
|
|||||||
@@ -0,0 +1,309 @@
|
|||||||
|
package com.fizz.business.service.strip;
|
||||||
|
|
||||||
|
import com.fizz.business.constants.enums.DeviceEnum;
|
||||||
|
import com.fizz.business.constants.enums.L1OperateMatEnum;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureCoatMessage;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureEntryMessage;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureExitMessage;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureFurnaceMessage;
|
||||||
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
|
import com.fizz.business.dto.SegValue;
|
||||||
|
import com.fizz.business.dto.SegmentDTO;
|
||||||
|
import com.fizz.business.form.L1OperateMatForm;
|
||||||
|
import com.fizz.business.service.TrackService;
|
||||||
|
import com.fizz.business.service.impl.SegmentService;
|
||||||
|
import com.fizz.business.utils.MatmapUtil;
|
||||||
|
import com.fizz.business.utils.WebSocketUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import static com.fizz.business.constants.enums.DeviceEnum.WELDER;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SegmentTrackerService {
|
||||||
|
|
||||||
|
private final StripPositionService stripPositionService;
|
||||||
|
private final TrackService trackService;
|
||||||
|
private final SegmentService segmentService; // 注入新创建的段服务
|
||||||
|
|
||||||
|
private int traceCount = 0;
|
||||||
|
private boolean firstMeasure = true;
|
||||||
|
private BigDecimal weldLength = BigDecimal.ZERO;
|
||||||
|
private int coilSegNum = 1;
|
||||||
|
|
||||||
|
private final Deque<SegmentDTO> listSegment = new ConcurrentLinkedDeque<>();
|
||||||
|
private static final double SEGSTRIPLEN = 2.0;
|
||||||
|
private static final int MAX_SEG_COUNT = 2000;
|
||||||
|
private final ConcurrentMap<String, Set<DeviceEnum>> coilReachedDevices = new ConcurrentHashMap<>();
|
||||||
|
private static final double LOWSPEEDLIMIT = 0.05;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【主入口】
|
||||||
|
* 负责处理新的测量数据,生成新段,并对新到达的设备做一次性快照。
|
||||||
|
*/
|
||||||
|
public void handleMeasure(String coilId,
|
||||||
|
BigDecimal entryLengthAtWelder,
|
||||||
|
AppMeasureEntryMessage entry,
|
||||||
|
AppMeasureFurnaceMessage furnace,
|
||||||
|
AppMeasureCoatMessage coat,
|
||||||
|
AppMeasureExitMessage exit) {
|
||||||
|
|
||||||
|
// 1. 首次测量初始化或新卷判定
|
||||||
|
BigDecimal weldDev;
|
||||||
|
if (firstMeasure || entryLengthAtWelder.compareTo(weldLength) < 0) {
|
||||||
|
weldDev = entryLengthAtWelder; // 新卷偏移量等于当前长度
|
||||||
|
coilSegNum = 1;
|
||||||
|
weldLength = entryLengthAtWelder;
|
||||||
|
firstMeasure = false;
|
||||||
|
listSegment.clear(); // 清空旧段
|
||||||
|
coilReachedDevices.remove(coilId); // 清空旧钢卷的快照记录
|
||||||
|
log.info("New coil detected or initialized:{} " ,coilId);
|
||||||
|
} else {
|
||||||
|
weldDev = entryLengthAtWelder.subtract(weldLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新焊机长度
|
||||||
|
weldLength = entryLengthAtWelder;
|
||||||
|
|
||||||
|
// trace 控制
|
||||||
|
traceCount++;
|
||||||
|
if (traceCount > 5) {
|
||||||
|
log.info(String.format("Trace: weldLen=%.2f, speed=%s",
|
||||||
|
entryLengthAtWelder, procStripSpeed(entry, furnace, exit)));
|
||||||
|
traceCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 2. 检查是否达到生成新段的条件
|
||||||
|
BigDecimal segThreshold = BigDecimal.valueOf(coilSegNum * SEGSTRIPLEN);
|
||||||
|
if (entryLengthAtWelder.compareTo(segThreshold) >= 0) {
|
||||||
|
|
||||||
|
// 2.1. 创建新的 SegmentDTO 并初始化基本位置
|
||||||
|
SegmentDTO newSeg = createNewSegment(coilId, entryLengthAtWelder);
|
||||||
|
|
||||||
|
// 2.3. 将新段添加到队列中
|
||||||
|
listSegment.addLast(newSeg);
|
||||||
|
if (listSegment.size() > MAX_SEG_COUNT) {
|
||||||
|
listSegment.removeFirst();
|
||||||
|
}
|
||||||
|
coilSegNum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 处理队列中所有已存在的段
|
||||||
|
treatSegAsync(entry, furnace, coat, exit, weldDev);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【核心功能】
|
||||||
|
* 遍历所有已存在的段,更新其位置,并累积其在设备区域内的实时数据。
|
||||||
|
* 这部分逻辑只负责“移动”和“累积”。
|
||||||
|
*/
|
||||||
|
public void treatSeg(AppMeasureEntryMessage entry,
|
||||||
|
AppMeasureFurnaceMessage furnace,
|
||||||
|
AppMeasureCoatMessage coat,
|
||||||
|
AppMeasureExitMessage exit,
|
||||||
|
BigDecimal weldDev) {
|
||||||
|
if (listSegment.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal celLength = entry != null ? entry.getCelLength() : BigDecimal.ZERO;
|
||||||
|
BigDecimal cxlLength = exit != null ? exit.getCxlLength() : BigDecimal.ZERO;
|
||||||
|
|
||||||
|
Iterator<SegmentDTO> iterator = listSegment.descendingIterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
SegmentDTO segment = iterator.next();
|
||||||
|
|
||||||
|
// 更新段在产线上的位置
|
||||||
|
segment.setHeadPos(segment.getHeadPos().add(weldDev));
|
||||||
|
segment.setTailPos(segment.getTailPos().add(weldDev));
|
||||||
|
|
||||||
|
// 遍历所有设备,累积段在设备区域内的数据
|
||||||
|
for (DeviceEnum device : DeviceEnum.values()) {
|
||||||
|
double currentDevicePos = stripPositionService.calculate(device, celLength, cxlLength);
|
||||||
|
|
||||||
|
// 判断段是否位于设备的“长区域”内
|
||||||
|
if (segment.getHeadPos().compareTo(BigDecimal.valueOf(currentDevicePos)) > 0 &&
|
||||||
|
segment.getTailPos().compareTo(BigDecimal.valueOf(currentDevicePos)) < 0) {
|
||||||
|
|
||||||
|
double currentSpeed = getSpeedForDevice(device, entry, furnace, exit);
|
||||||
|
if (currentSpeed > LOWSPEEDLIMIT) {
|
||||||
|
for (String fieldName : device.getParamFields()) {
|
||||||
|
Object message = getMessageForDevice(device, entry, furnace, coat, exit);
|
||||||
|
if (message != null) {
|
||||||
|
BigDecimal value = getFieldFromMessage(message, fieldName);
|
||||||
|
setSegValue(segment.getTotalValues(), fieldName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 出厂判断
|
||||||
|
double exitPlantPos = stripPositionService.calculate(DeviceEnum.TR, celLength, cxlLength);
|
||||||
|
if (segment.getTailPos().compareTo(BigDecimal.valueOf(exitPlantPos)) >= 0) {
|
||||||
|
System.out.println("钢卷 " + segment.getEnCoilID() + " 的段号 " + segment.getSegNo() + " 已离开产线,开始持久化数据。");
|
||||||
|
segmentService.saveTotalSegment(segment); // 调用服务进行持久化
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 新增的辅助方法,将逻辑封装起来 ---
|
||||||
|
/**
|
||||||
|
* 【异步方法】
|
||||||
|
* 异步处理队列中所有已存在的段,更新其位置和累积数据。
|
||||||
|
*/
|
||||||
|
@Async("taskExecutor") // 指定使用名为 "taskExecutor" 的线程池
|
||||||
|
public void treatSegAsync(AppMeasureEntryMessage entry,
|
||||||
|
AppMeasureFurnaceMessage furnace,
|
||||||
|
AppMeasureCoatMessage coat,
|
||||||
|
AppMeasureExitMessage exit,
|
||||||
|
BigDecimal weldDev) {
|
||||||
|
// 调用原有的同步方法
|
||||||
|
this.treatSeg(entry, furnace, coat, exit, weldDev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建并初始化一个新的 SegmentDTO。
|
||||||
|
*/
|
||||||
|
private SegmentDTO createNewSegment(String coilId, BigDecimal entryLengthAtWelder) {
|
||||||
|
SegmentDTO seg = new SegmentDTO();
|
||||||
|
seg.setSegNo(coilSegNum);
|
||||||
|
seg.setEnCoilID(coilId);
|
||||||
|
|
||||||
|
if (coilSegNum == 1) {
|
||||||
|
// 第一个段的特殊处理
|
||||||
|
seg.setStartPos(BigDecimal.ZERO);
|
||||||
|
seg.setEndPos(entryLengthAtWelder);
|
||||||
|
seg.setSegLen(entryLengthAtWelder);
|
||||||
|
seg.setHeadPos(entryLengthAtWelder);
|
||||||
|
seg.setTailPos(BigDecimal.ZERO);
|
||||||
|
} else {
|
||||||
|
// 后续段的计算
|
||||||
|
SegmentDTO prev = listSegment.peekLast();
|
||||||
|
seg.setStartPos(prev.getEndPos());
|
||||||
|
seg.setEndPos(entryLengthAtWelder);
|
||||||
|
seg.setSegLen(seg.getEndPos().subtract(seg.getStartPos()));
|
||||||
|
// 这两个位置是全线绝对位置,后续会通过 weldDev 动态更新
|
||||||
|
seg.setHeadPos(entryLengthAtWelder);
|
||||||
|
seg.setTailPos(seg.getEndPos().subtract(seg.getSegLen()));
|
||||||
|
}
|
||||||
|
return seg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --- 辅助方法,与消息处理和反射相关 ---
|
||||||
|
|
||||||
|
private Object getMessageForDevice(DeviceEnum device, AppMeasureEntryMessage entry, AppMeasureFurnaceMessage furnace, AppMeasureCoatMessage coat, AppMeasureExitMessage exit) {
|
||||||
|
if (device.getDesc().contains("开卷机") || device.getDesc().contains("活套") || device.getDesc().contains("焊机")) {
|
||||||
|
return entry;
|
||||||
|
} else if (device.getDesc().contains("清洗段") || device.getDesc().contains("退火炉")) {
|
||||||
|
return furnace;
|
||||||
|
} else if (device.getDesc().contains("涂机")) {
|
||||||
|
return coat;
|
||||||
|
} else {
|
||||||
|
return exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getSpeedForDevice(DeviceEnum device, AppMeasureEntryMessage entry, AppMeasureFurnaceMessage furnace, AppMeasureExitMessage exit) {
|
||||||
|
if (device.getDesc().contains("开卷机") || device.getDesc().contains("活套") || device.getDesc().contains("焊机")) {
|
||||||
|
return entry != null && entry.getStripSpeed() != null ? entry.getStripSpeed().doubleValue() : 0.0;
|
||||||
|
} else if (device.getDesc().contains("清洗段") || device.getDesc().contains("退火炉")) {
|
||||||
|
return furnace != null && furnace.getStripSpeed() != null ? furnace.getStripSpeed().doubleValue() : 0.0;
|
||||||
|
} else {
|
||||||
|
return exit != null && exit.getSpeedExitSection() != null ? exit.getSpeedExitSection().doubleValue() : 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double procStripSpeed(AppMeasureEntryMessage entry, AppMeasureFurnaceMessage furnace, AppMeasureExitMessage exit) {
|
||||||
|
if (entry != null && entry.getStripSpeed() != null) return entry.getStripSpeed().doubleValue();
|
||||||
|
if (furnace != null && furnace.getStripSpeed() != null) return furnace.getStripSpeed().doubleValue();
|
||||||
|
if (exit != null && exit.getSpeedExitSection() != null) return exit.getSpeedExitSection().doubleValue();
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal getFieldFromMessage(Object message, String fieldName) {
|
||||||
|
if (message == null || fieldName == null) return null;
|
||||||
|
try {
|
||||||
|
String getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
|
||||||
|
Method getter = message.getClass().getMethod(getterName);
|
||||||
|
Object value = getter.invoke(message);
|
||||||
|
|
||||||
|
if (value instanceof BigDecimal) {
|
||||||
|
return (BigDecimal) value;
|
||||||
|
} else if (value instanceof Number) {
|
||||||
|
return BigDecimal.valueOf(((Number) value).doubleValue());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Error getting field " + fieldName + " from message: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSegValue(Map<String, SegValue> segValues, String key, BigDecimal value) {
|
||||||
|
if (value != null) {
|
||||||
|
segValues.computeIfAbsent(key, k -> new SegValue()).add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【新方法】
|
||||||
|
* 专门用于处理钢卷头部在设备间的移动和物料跟踪。
|
||||||
|
* 这部分逻辑包含了对 Redis/DB 的写入,最适合异步化。
|
||||||
|
*/
|
||||||
|
@Async("taskExecutor")
|
||||||
|
public void trackCoilHeadPosition(String coilId, BigDecimal headPos,
|
||||||
|
AppMeasureEntryMessage entry, AppMeasureExitMessage exit) {
|
||||||
|
|
||||||
|
Set<DeviceEnum> prevReached = coilReachedDevices.computeIfAbsent(coilId, k -> Collections.newSetFromMap(new ConcurrentHashMap<>()));
|
||||||
|
|
||||||
|
BigDecimal celLength = entry != null ? entry.getCelLength() : BigDecimal.ZERO;
|
||||||
|
BigDecimal cxlLength = exit != null ? exit.getCxlLength() : BigDecimal.ZERO;
|
||||||
|
|
||||||
|
for (DeviceEnum d : DeviceEnum.values()) {
|
||||||
|
double dynPos = stripPositionService.calculate(d, celLength, cxlLength);
|
||||||
|
|
||||||
|
// 判断钢卷的头部是否首次到达该设备
|
||||||
|
if (headPos.compareTo(BigDecimal.valueOf(dynPos)) >= 0) {
|
||||||
|
if (!prevReached.contains(d)) {
|
||||||
|
|
||||||
|
// 1. 如果是焊机,则调用 CRM 更新计划状态
|
||||||
|
if (d == WELDER) {
|
||||||
|
|
||||||
|
MatmapDTO matmap = MatmapUtil.getMatmap(WELDER.getIdx());
|
||||||
|
trackService.l1OperateMat(L1OperateMatForm.builder()
|
||||||
|
.entryMatId(coilId)
|
||||||
|
.planId(matmap.getPlanId())
|
||||||
|
.porIdx(entry.getPayOffReelNumber())
|
||||||
|
.operation(L1OperateMatEnum.PRODUCING)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 更新 Matmap
|
||||||
|
MatmapUtil.setMatId(d.getIdx(), coilId);
|
||||||
|
WebSocketUtil.sendMatmapMsg();
|
||||||
|
// 3. 标记为已到达,防止重复操作
|
||||||
|
prevReached.add(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.fizz.business.service.strip;
|
||||||
|
|
||||||
|
import com.fizz.business.constants.enums.DeviceEnum;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureEntryMessage;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureExitMessage;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 位置计算服务 —— 根据 entry.stripLocation(焊机参考)和活套长度动态判断设备的比较位置
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class StripPositionService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算设备在 entry 坐标系的“比较位置”
|
||||||
|
*
|
||||||
|
* 规则:
|
||||||
|
* - device.basePosition < ENL_MIN : 不加活套
|
||||||
|
* - ENL_MIN <= device.basePosition < CXL_MIN : 加 celLength
|
||||||
|
* - >= CXL_MIN : 加 cxlLength
|
||||||
|
*/
|
||||||
|
public double calculate(DeviceEnum device, BigDecimal celLength, BigDecimal cxlLength) {
|
||||||
|
double base = device.getBasePosition();
|
||||||
|
double cel = celLength == null ? 0.0 : celLength.doubleValue();
|
||||||
|
double cxl = cxlLength == null ? 0.0 : cxlLength.doubleValue();
|
||||||
|
|
||||||
|
double enlMin = findEnlMin();
|
||||||
|
double cxlMin = findCxlMin();
|
||||||
|
|
||||||
|
if (base < enlMin) {
|
||||||
|
return base;
|
||||||
|
} else if (base < cxlMin) {
|
||||||
|
return base + cel;
|
||||||
|
} else {
|
||||||
|
return base + cxl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double calculate(DeviceEnum device,AppMeasureEntryMessage entry,
|
||||||
|
AppMeasureExitMessage exit) {
|
||||||
|
BigDecimal cel = entry == null ? null : entry.getCelLength();
|
||||||
|
BigDecimal cxl = exit == null ? null : exit.getCxlLength();
|
||||||
|
return calculate(device, cel, cxl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double findEnlMin() {
|
||||||
|
double min = Double.MAX_VALUE;
|
||||||
|
for (DeviceEnum d : DeviceEnum.values()) {
|
||||||
|
if (d.name().startsWith("ENL")) {
|
||||||
|
min = Math.min(min, d.getBasePosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min == Double.MAX_VALUE ? 0.0 : min;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double findCxlMin() {
|
||||||
|
double min = Double.MAX_VALUE;
|
||||||
|
for (DeviceEnum d : DeviceEnum.values()) {
|
||||||
|
if (d.name().startsWith("CXL")) {
|
||||||
|
min = Math.min(min, d.getBasePosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min == Double.MAX_VALUE ? Double.MAX_VALUE : min;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,23 +1,21 @@
|
|||||||
package com.fizz.business.utils;
|
package com.fizz.business.utils;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
import com.fizz.business.constants.enums.DeviceEnum;
|
import com.fizz.business.constants.enums.DeviceEnum;
|
||||||
import com.fizz.business.domain.DeviceDefine;
|
import com.fizz.business.domain.DeviceDefine;
|
||||||
import com.fizz.business.dto.*;
|
import com.fizz.business.dto.CoilHeadDTO;
|
||||||
|
import com.fizz.business.dto.CoilPositionDTO;
|
||||||
|
import com.fizz.business.dto.L1CoilLineMeasureDTO;
|
||||||
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
import com.fizz.business.service.client.RedisCacheManager;
|
import com.fizz.business.service.client.RedisCacheManager;
|
||||||
import com.fizz.business.service.impl.BeanFactory;
|
import com.fizz.business.service.impl.BeanFactory;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.Objects;
|
||||||
|
|
||||||
import static com.fizz.business.constants.CommonConstants.CoilMeasure.BEFORE_TR_IDX;
|
import static com.fizz.business.constants.CommonConstants.CoilMeasure.BEFORE_TR_IDX;
|
||||||
import static com.fizz.business.service.client.LocalCacheManager.DEVICE_DEFINE_MAP;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,9 +65,7 @@ public class CoilMeasUtil {
|
|||||||
|
|
||||||
Integer trIdx = null;
|
Integer trIdx = null;
|
||||||
if (trCode == 1) {
|
if (trCode == 1) {
|
||||||
trIdx = DeviceEnum.TR1.getIdx();
|
trIdx = DeviceEnum.TR.getIdx();
|
||||||
} else if (trCode == 2) {
|
|
||||||
trIdx = DeviceEnum.TR2.getIdx();
|
|
||||||
} else {
|
} else {
|
||||||
log.warn("W: invalid working TR, trCode={}", trCode);
|
log.warn("W: invalid working TR, trCode={}", trCode);
|
||||||
}
|
}
|
||||||
@@ -81,7 +77,7 @@ public class CoilMeasUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<Integer> getTrIdxList() {
|
public static List<Integer> getTrIdxList() {
|
||||||
return Lists.newArrayList(DeviceEnum.TR1.getIdx(), DeviceEnum.TR2.getIdx());
|
return Lists.newArrayList(DeviceEnum.TR.getIdx());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,147 +89,4 @@ public class CoilMeasUtil {
|
|||||||
return BEFORE_TR_IDX.getIdx();
|
return BEFORE_TR_IDX.getIdx();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double initStripLocation(double stripLocation) {
|
|
||||||
if (stripLocation < 0) {
|
|
||||||
stripLocation = 0;
|
|
||||||
} else if (stripLocation > 25000) {
|
|
||||||
stripLocation = 25000;
|
|
||||||
}
|
|
||||||
return stripLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DeviceDefine matchDevice(double posLen, double entryLoopLen, double exitLoopLen) {
|
|
||||||
DeviceDefine mCEL = DEVICE_DEFINE_MAP.get(DeviceEnum.CEL.name()); // 入口活套
|
|
||||||
DeviceDefine mCXL = DEVICE_DEFINE_MAP.get(DeviceEnum.CXL.name()); // 出口活套
|
|
||||||
for (DeviceDefine device : DEVICE_DEFINE_MAP.values()) {
|
|
||||||
Double start = device.getPositionLengthStart();
|
|
||||||
Double end = device.getPositionLengthEnd();
|
|
||||||
// 入口活套之后的设备,需要加上entryLoopLen
|
|
||||||
if (device.getPosIdx() >= mCEL.getPosIdx()) {
|
|
||||||
// start = NumberUtil.add(start, entryLoopLen);
|
|
||||||
end = NumberUtil.add(end, entryLoopLen);
|
|
||||||
}
|
|
||||||
// 出口活套之后的设备,还需要加上exitLoopLen
|
|
||||||
if (device.getPosIdx() >= mCXL.getPosIdx()) {
|
|
||||||
// start = NumberUtil.add(start, exitLoopLen);
|
|
||||||
end = NumberUtil.add(end, exitLoopLen);
|
|
||||||
}
|
|
||||||
if (posLen >= start && posLen < end) {
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CoilPositionDTO buildCoilPos(L1CoilLineMeasureDTO measureDTO, List<CoilHeadDTO> headList) {
|
|
||||||
List<CoilPositionDTO.CoilStripLocation> coilStripLocationList = Lists.newArrayList();
|
|
||||||
Integer workPor = measureDTO.getWorkPor();
|
|
||||||
Integer workTr = measureDTO.getWorkTr();
|
|
||||||
|
|
||||||
CoilHeadDTO prevHead = BeanFactory.getBean(RedisCacheManager.class).getPrevHead();
|
|
||||||
if (Objects.nonNull(prevHead)) {
|
|
||||||
coilStripLocationList.add(
|
|
||||||
CoilPositionDTO.CoilStripLocation.builder()
|
|
||||||
.matId(prevHead.getMatId())
|
|
||||||
.planId(prevHead.getPlanId())
|
|
||||||
.planNo(prevHead.getPlanNo())
|
|
||||||
.porId(prevHead.getPorIdx())
|
|
||||||
.stripLocation(99999).build());
|
|
||||||
}
|
|
||||||
headList.forEach(head -> coilStripLocationList.add(
|
|
||||||
CoilPositionDTO.CoilStripLocation.builder()
|
|
||||||
.matId(head.getMatId())
|
|
||||||
.planId(head.getPlanId())
|
|
||||||
.planNo(head.getPlanNo())
|
|
||||||
.porId(head.getPorIdx())
|
|
||||||
.stripLocation(head.getPos()).build()));
|
|
||||||
|
|
||||||
// 两个开卷机时,需要设置另一个未运行的开卷机上的钢卷数据
|
|
||||||
Integer anotherPorIdx = getAnotherPorIdx(workPor);
|
|
||||||
if (Objects.nonNull(anotherPorIdx)) {
|
|
||||||
MatmapDTO matmap = MatmapUtil.getMatmap(anotherPorIdx);
|
|
||||||
coilStripLocationList.add(
|
|
||||||
CoilPositionDTO.CoilStripLocation.builder()
|
|
||||||
.matId(matmap.getMatId())
|
|
||||||
.planId(matmap.getPlanId())
|
|
||||||
.planNo(matmap.getPlanNo())
|
|
||||||
.porId(anotherPorIdx)
|
|
||||||
.stripLocation(0).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 当前开卷机与焊机的卷号不同时,需要设置当前开卷机上的钢卷数据(这种情况只出现在只有一个开卷机运行的时候)
|
|
||||||
Integer porIdx = CoilMeasUtil.getPorIdx(workPor);
|
|
||||||
MatmapDTO welderCoil = MatmapUtil.getMatmap(DeviceEnum.WELDER.getIdx());
|
|
||||||
if (Objects.nonNull(porIdx) && MatmapUtil.already(welderCoil)) {
|
|
||||||
MatmapDTO porCoil = MatmapUtil.getMatmap(porIdx);
|
|
||||||
if (!Objects.equals(welderCoil.getMatId(), porCoil.getMatId())) {
|
|
||||||
coilStripLocationList.add(
|
|
||||||
CoilPositionDTO.CoilStripLocation.builder()
|
|
||||||
.matId(porCoil.getMatId())
|
|
||||||
.planId(porCoil.getPlanId())
|
|
||||||
.planNo(porCoil.getPlanNo())
|
|
||||||
.porId(porIdx)
|
|
||||||
.stripLocation(0).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CoilPositionDTO.builder()
|
|
||||||
.coilStripLocationList(coilStripLocationList)
|
|
||||||
.entryLoopLen(measureDTO.getEntryLoopLength())
|
|
||||||
.exitLoopLen(measureDTO.getExitLoopLength())
|
|
||||||
.entryLoopPer(measureDTO.getEntryLoopPercent())
|
|
||||||
.exitLoopLPer(measureDTO.getExitLoopPercent())
|
|
||||||
.entrySpeed(measureDTO.getInSpeed())
|
|
||||||
.technologySpeed(measureDTO.getUnitSpeed())
|
|
||||||
.exitSpeed(measureDTO.getOutSpeed())
|
|
||||||
.porId(CoilMeasUtil.getPorIdx(workPor))
|
|
||||||
.trId(CoilMeasUtil.getTrIdx(workTr))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double getPorSpeed(L1CoilLineMeasureDTO measureDTO) {
|
|
||||||
return measureDTO.getUnitSpeed();
|
|
||||||
}
|
|
||||||
|
|
||||||
// public static List<String> getParamKey(String deviceName) {
|
|
||||||
// List<PointConfigDTO> list = DEVICE_PARAM_MAP.get(deviceName);
|
|
||||||
// if (CollUtil.isEmpty(list)) {
|
|
||||||
// return Collections.emptyList();
|
|
||||||
// }
|
|
||||||
// return list.stream().map(PointConfigDTO::getParam).collect(Collectors.toList());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static String getParamKey(String deviceName, String paramDesc) {
|
|
||||||
// List<PointConfigDTO> list = DEVICE_PARAM_MAP.get(deviceName);
|
|
||||||
// if (CollUtil.isEmpty(list)) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// List<String> keys = list.stream()
|
|
||||||
// .filter(p -> paramDesc.equals(p.getDesc()))
|
|
||||||
// .map(PointConfigDTO::getParam)
|
|
||||||
// .collect(Collectors.toList());
|
|
||||||
// if (CollUtil.isEmpty(keys)) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// return keys.get(0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public static List<String> getParamDesc(String deviceName) {
|
|
||||||
// List<PointConfigDTO> list = DEVICE_PARAM_MAP.get(deviceName);
|
|
||||||
// if (CollUtil.isEmpty(list)) {
|
|
||||||
// return Collections.emptyList();
|
|
||||||
// }
|
|
||||||
// return list.stream().map(PointConfigDTO::getDesc).collect(Collectors.toList());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static LinkedHashMap<String, String> getParamMap(String deviceName) {
|
|
||||||
// List<PointConfigDTO> list = DEVICE_PARAM_MAP.get(deviceName);
|
|
||||||
// if (CollUtil.isEmpty(list)) {
|
|
||||||
// return Maps.newLinkedHashMap();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return list.stream().collect(Collectors.toMap(PointConfigDTO::getParam, PointConfigDTO::getDesc, (k1, k2) -> k1, LinkedHashMap::new));
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import cn.hutool.json.JSONUtil;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.fizz.business.constants.CommonConstants;
|
import com.fizz.business.constants.CommonConstants;
|
||||||
import com.fizz.business.constants.enums.WsTypeEnum;
|
import com.fizz.business.constants.enums.WsTypeEnum;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureEntryMessage;
|
||||||
|
import com.fizz.business.domain.msg.AppMeasureMessage;
|
||||||
import com.fizz.business.dto.CoilPositionDTO;
|
import com.fizz.business.dto.CoilPositionDTO;
|
||||||
import com.fizz.business.dto.L1CoilLineMeasureDTO;
|
import com.fizz.business.dto.L1CoilLineMeasureDTO;
|
||||||
import com.fizz.business.dto.MatmapDTO;
|
import com.fizz.business.dto.MatmapDTO;
|
||||||
@@ -79,6 +81,13 @@ public class WebSocketUtil {
|
|||||||
sendMessage(WsTypeEnum.track_measure, JSONUtil.toJsonStr(measureDTO));
|
sendMessage(WsTypeEnum.track_measure, JSONUtil.toJsonStr(measureDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void sendMeasureMsg(AppMeasureMessage measureDTO) {
|
||||||
|
|
||||||
|
|
||||||
|
sendMessage(WsTypeEnum.track_measure, JSONUtil.toJsonStr(measureDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void sendMatmapMsg() {
|
public static void sendMatmapMsg() {
|
||||||
List<MatmapDTO> list = MatmapUtil.getMatmapList();
|
List<MatmapDTO> list = MatmapUtil.getMatmapList();
|
||||||
if (CollUtil.isEmpty(list)) return;
|
if (CollUtil.isEmpty(list)) return;
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.fizz.business.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(name = "ReportDetailVO", description = "钢卷明细信息")
|
||||||
|
public class ReportDetailVO {
|
||||||
|
|
||||||
|
@Schema(description = "成品卷号")
|
||||||
|
private String exitMatId;
|
||||||
|
|
||||||
|
@Schema(description = "原料卷号")
|
||||||
|
private String entryMatId;
|
||||||
|
|
||||||
|
@Schema(description = "班号")
|
||||||
|
private String groupNo;
|
||||||
|
|
||||||
|
@Schema(description = "组号")
|
||||||
|
private String shiftNo;
|
||||||
|
|
||||||
|
@Schema(description = "钢种")
|
||||||
|
private String steelGrade;
|
||||||
|
|
||||||
|
@Schema(description = "成品宽度")
|
||||||
|
private Double exitWidth;
|
||||||
|
|
||||||
|
@Schema(description = "成品长度")
|
||||||
|
private Double exitLength;
|
||||||
|
|
||||||
|
@Schema(description = "理论重量")
|
||||||
|
private Double theoryWeight;
|
||||||
|
|
||||||
|
@Schema(description = "实际重量")
|
||||||
|
private Double actualWeight;
|
||||||
|
|
||||||
|
@Schema(description = "成品厚度")
|
||||||
|
private Double exitThickness;
|
||||||
|
|
||||||
|
@Schema(description = "上线时间")
|
||||||
|
private LocalDateTime onlineTime;
|
||||||
|
|
||||||
|
@Schema(description = "结束时间")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.fizz.business.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(name = "ReportSummaryVO", description = "报表汇总统计结果")
|
||||||
|
public class ReportSummaryVO {
|
||||||
|
|
||||||
|
// 汇总指标
|
||||||
|
@Schema(description = "总成品宽度")
|
||||||
|
private Double totalExitWidth;
|
||||||
|
|
||||||
|
@Schema(description = "总成品长度")
|
||||||
|
private Double totalExitLength;
|
||||||
|
|
||||||
|
@Schema(description = "总理论重量")
|
||||||
|
private Double totalTheoryWeight;
|
||||||
|
|
||||||
|
@Schema(description = "总实际重量")
|
||||||
|
private Double totalActualWeight;
|
||||||
|
|
||||||
|
@Schema(description = "总成品厚度")
|
||||||
|
private Double totalExitThickness;
|
||||||
|
|
||||||
|
// 平均指标
|
||||||
|
@Schema(description = "平均成品宽度")
|
||||||
|
private Double avgExitWidth;
|
||||||
|
|
||||||
|
@Schema(description = "平均成品长度")
|
||||||
|
private Double avgExitLength;
|
||||||
|
|
||||||
|
@Schema(description = "平均理论重量")
|
||||||
|
private Double avgTheoryWeight;
|
||||||
|
|
||||||
|
@Schema(description = "平均实际重量")
|
||||||
|
private Double avgActualWeight;
|
||||||
|
|
||||||
|
@Schema(description = "平均成品厚度")
|
||||||
|
private Double avgExitThickness;
|
||||||
|
|
||||||
|
// 新增指标
|
||||||
|
@Schema(description = "钢卷总数")
|
||||||
|
private Long coilCount;
|
||||||
|
|
||||||
|
@Schema(description = "原料总重(去重计算)")
|
||||||
|
private Double totalEntryWeight;
|
||||||
|
|
||||||
|
@Schema(description = "成材率(成品实际重量/原料重量)")
|
||||||
|
private Double yieldRate;
|
||||||
|
}
|
||||||
@@ -3,4 +3,139 @@
|
|||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
<mapper namespace="com.fizz.business.mapper.CrmPdoExcoilMapper">
|
<mapper namespace="com.fizz.business.mapper.CrmPdoExcoilMapper">
|
||||||
|
|
||||||
|
<select id="getReportSummary" resultType="com.fizz.business.vo.ReportSummaryVO">
|
||||||
|
SELECT
|
||||||
|
-- 总计
|
||||||
|
SUM(exit_width) AS totalExitWidth,
|
||||||
|
SUM(exit_length) AS totalExitLength,
|
||||||
|
SUM(theory_weight) AS totalTheoryWeight,
|
||||||
|
SUM(actual_weight) AS totalActualWeight,
|
||||||
|
SUM(exit_thickness) AS totalExitThickness,
|
||||||
|
|
||||||
|
-- 平均
|
||||||
|
AVG(exit_width) AS avgExitWidth,
|
||||||
|
AVG(exit_length) AS avgExitLength,
|
||||||
|
AVG(theory_weight) AS avgTheoryWeight,
|
||||||
|
AVG(actual_weight) AS avgActualWeight,
|
||||||
|
AVG(exit_thickness) AS avgExitThickness,
|
||||||
|
|
||||||
|
-- 总数
|
||||||
|
COUNT(DISTINCT exit_mat_id) AS coilCount,
|
||||||
|
|
||||||
|
-- 原料总重(去重 entry_mat_id)
|
||||||
|
(SELECT SUM(t.entry_weight)
|
||||||
|
FROM (
|
||||||
|
SELECT entry_mat_id, MAX(entry_weight) AS entry_weight
|
||||||
|
FROM crm_pdo_excoil
|
||||||
|
WHERE del_flag = 0
|
||||||
|
<if test="groupNo != null and groupNo != ''">
|
||||||
|
AND group_no = #{groupNo}
|
||||||
|
</if>
|
||||||
|
<if test="shiftNo != null and shiftNo != ''">
|
||||||
|
AND shift_no = #{shiftNo}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null">
|
||||||
|
AND end_time <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null">
|
||||||
|
AND end_time <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
GROUP BY entry_mat_id
|
||||||
|
) t
|
||||||
|
) AS totalEntryWeight,
|
||||||
|
|
||||||
|
-- 成材率
|
||||||
|
CASE
|
||||||
|
WHEN (SELECT SUM(tt.entry_weight)
|
||||||
|
FROM (
|
||||||
|
SELECT entry_mat_id, MAX(entry_weight) AS entry_weight
|
||||||
|
FROM crm_pdo_excoil
|
||||||
|
WHERE del_flag = 0
|
||||||
|
<if test="groupNo != null and groupNo != ''">
|
||||||
|
AND group_no = #{groupNo}
|
||||||
|
</if>
|
||||||
|
<if test="shiftNo != null and shiftNo != ''">
|
||||||
|
AND shift_no = #{shiftNo}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null">
|
||||||
|
AND end_time <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null">
|
||||||
|
AND end_time <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
GROUP BY entry_mat_id
|
||||||
|
) tt
|
||||||
|
) > 0
|
||||||
|
THEN SUM(actual_weight) /
|
||||||
|
(SELECT SUM(tt.entry_weight)
|
||||||
|
FROM (
|
||||||
|
SELECT entry_mat_id, MAX(entry_weight) AS entry_weight
|
||||||
|
FROM crm_pdo_excoil
|
||||||
|
WHERE del_flag = 0
|
||||||
|
<if test="groupNo != null and groupNo != ''">
|
||||||
|
AND group_no = #{groupNo}
|
||||||
|
</if>
|
||||||
|
<if test="shiftNo != null and shiftNo != ''">
|
||||||
|
AND shift_no = #{shiftNo}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null">
|
||||||
|
AND end_time <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null">
|
||||||
|
AND end_time <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
GROUP BY entry_mat_id
|
||||||
|
) tt
|
||||||
|
)
|
||||||
|
ELSE 0
|
||||||
|
END AS yieldRate
|
||||||
|
|
||||||
|
FROM crm_pdo_excoil
|
||||||
|
WHERE del_flag = 0
|
||||||
|
<if test="groupNo != null and groupNo != ''">
|
||||||
|
AND group_no = #{groupNo}
|
||||||
|
</if>
|
||||||
|
<if test="shiftNo != null and shiftNo != ''">
|
||||||
|
AND shift_no = #{shiftNo}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null">
|
||||||
|
AND end_time <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null">
|
||||||
|
AND end_time <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="getReportDetails" resultType="com.fizz.business.vo.ReportDetailVO">
|
||||||
|
SELECT
|
||||||
|
exit_mat_id AS exitMatId,
|
||||||
|
entry_mat_id AS entryMatId,
|
||||||
|
group_no AS groupNo,
|
||||||
|
shift_no AS shiftNo,
|
||||||
|
steel_grade AS steelGrade,
|
||||||
|
exit_width AS exitWidth,
|
||||||
|
exit_length AS exitLength,
|
||||||
|
theory_weight AS theoryWeight,
|
||||||
|
actual_weight AS actualWeight,
|
||||||
|
exit_thickness AS exitThickness,
|
||||||
|
online_time AS onlineTime,
|
||||||
|
end_time AS endTime
|
||||||
|
FROM crm_pdo_excoil
|
||||||
|
WHERE del_flag = 0
|
||||||
|
<if test="groupNo != null and groupNo != ''">
|
||||||
|
AND group_no = #{groupNo}
|
||||||
|
</if>
|
||||||
|
<if test="shiftNo != null and shiftNo != ''">
|
||||||
|
AND shift_no = #{shiftNo}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null">
|
||||||
|
AND end_time <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null">
|
||||||
|
AND end_time <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
ORDER BY end_time ASC
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
|
|||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启动程序
|
* 启动程序
|
||||||
@@ -11,6 +12,7 @@ import org.springframework.context.annotation.ComponentScan;
|
|||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@ComponentScan(basePackages = {"com.ruoyi","com.fizz"})
|
@ComponentScan(basePackages = {"com.ruoyi","com.fizz"})
|
||||||
|
@EnableAsync // 启用异步处理
|
||||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||||
public class RuoYiApplication
|
public class RuoYiApplication
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -74,9 +74,9 @@ spring:
|
|||||||
port: 6379
|
port: 6379
|
||||||
# 数据库索引
|
# 数据库索引
|
||||||
database: 0
|
database: 0
|
||||||
# 密码 abcd1234 fe2b3cef78b74d3692909bdcbdf46331 KeLunPu123!
|
# 密码 abcd1234 fe2b3cef78b74d3692909bdcbdf46331 KeLunPu123!
|
||||||
password: KeLunPu123!
|
# password: KeLunPu123!
|
||||||
#password:
|
password: abcd1234
|
||||||
# 连接超时时间
|
# 连接超时时间
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
lettuce:
|
lettuce:
|
||||||
@@ -140,10 +140,10 @@ xss:
|
|||||||
# 匹配链接
|
# 匹配链接
|
||||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||||
|
|
||||||
#rocketmq:
|
#rocketmq:
|
||||||
#name-server: 127.0.0.1:9876
|
#name-server: 127.0.0.1:9876
|
||||||
#producer:
|
#producer:
|
||||||
#group: test
|
#group: test
|
||||||
|
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
api-docs:
|
||||||
|
|||||||
Reference in New Issue
Block a user