同步规程同步代码和录入监测代码

This commit is contained in:
2026-05-23 19:34:52 +08:00
parent 6b58f37616
commit 35ad50a79d
29 changed files with 2357 additions and 329 deletions

View File

@@ -1181,6 +1181,122 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
return list;
}
@Override
public List<WmsMaterialCoilVo> queryByEnterCoilNos(List<String> enterCoilNos) {
if (enterCoilNos == null || enterCoilNos.isEmpty()) {
return Collections.emptyList();
}
QueryWrapper<WmsMaterialCoil> qw = new QueryWrapper<>();
qw.in("mc.enter_coil_no", enterCoilNos).eq("mc.del_flag", 0);
return baseMapper.selectVoListWithDynamicJoin(qw);
}
@Override
public List<WmsMaterialCoilVo> queryPageForSpecSync(WmsMaterialCoilBo bo, int pageNum, int pageSize,
String syncStatus, String material, java.util.Set<Long> specIds) {
QueryWrapper<WmsMaterialCoil> qw = buildQueryWrapperPlus(bo);
applySpecSyncExtras(qw, syncStatus, material, specIds);
int offset = Math.max(0, (pageNum - 1) * pageSize);
qw.last("LIMIT " + offset + ", " + pageSize);
return baseMapper.selectVoListWithDynamicJoin(qw);
}
@Override
public Map<String, Object> countForSpecSync(WmsMaterialCoilBo bo, String material, java.util.Set<Long> specIds) {
QueryWrapper<WmsMaterialCoil> qw = buildQueryWrapperPlus(bo);
applySpecSyncExtras(qw, null, material, specIds);
return baseMapper.selectCountForSpecSync(qw);
}
private void applySpecSyncExtras(QueryWrapper<WmsMaterialCoil> qw, String syncStatus,
String material, java.util.Set<Long> specIds) {
if (StringUtils.isNotBlank(material)) {
String like = "%" + material.toLowerCase() + "%";
qw.apply("LOWER(CASE WHEN mc.item_type = 'raw_material' THEN COALESCE(rm.material,'') "
+ "ELSE COALESCE(p.material,'') END) LIKE {0}", like);
}
if (specIds != null && !specIds.isEmpty()) {
qw.in("mc.spec_id", specIds);
}
if ("synced".equals(syncStatus)) qw.isNotNull("mc.spec_id");
else if ("unsynced".equals(syncStatus)) qw.isNull("mc.spec_id");
}
@Override
public List<WmsMaterialCoilVo> queryByProcessedCoilIds(java.util.Collection<Long> coilIds,
String enterCoilNo, String currentCoilNo, String material, String qualityStatus,
String syncStatus, java.util.Set<Long> filterSpecIds, int offset, int pageSize) {
if (coilIds == null || coilIds.isEmpty()) return Collections.emptyList();
QueryWrapper<WmsMaterialCoil> qw = buildProcessedCoilQw(coilIds, enterCoilNo, currentCoilNo,
material, qualityStatus, syncStatus, filterSpecIds);
qw.last("LIMIT " + offset + ", " + pageSize);
return baseMapper.selectVoListWithDynamicJoin(qw);
}
@Override
public long countByProcessedCoilIds(java.util.Collection<Long> coilIds,
String enterCoilNo, String currentCoilNo, String material, String qualityStatus,
String syncStatus, java.util.Set<Long> filterSpecIds) {
if (coilIds == null || coilIds.isEmpty()) return 0L;
QueryWrapper<WmsMaterialCoil> qw = buildProcessedCoilQw(coilIds, enterCoilNo, currentCoilNo,
material, qualityStatus, syncStatus, filterSpecIds);
Map<String, Object> result = baseMapper.selectCountForSpecSync(qw);
if (result == null) return 0L;
Object total = result.get("total");
if (total == null) return 0L;
try { return Long.parseLong(total.toString()); } catch (NumberFormatException e) { return 0L; }
}
@Override
public java.util.Map<String, Long> getOverallSyncStats(java.util.Collection<Long> coilIds,
String enterCoilNo, String currentCoilNo, String material, String qualityStatus,
java.util.Set<Long> filterSpecIds) {
java.util.Map<String, Long> stats = new java.util.LinkedHashMap<>();
stats.put("total", 0L);
stats.put("synced", 0L);
stats.put("unsynced", 0L);
stats.put("movedOn", 0L);
if (coilIds == null || coilIds.isEmpty()) return stats;
// syncStatus=null → 不加 version_id 过滤,一次查出全量分组
QueryWrapper<WmsMaterialCoil> qw = buildProcessedCoilQw(
coilIds, enterCoilNo, currentCoilNo, material, qualityStatus, null, filterSpecIds);
Map<String, Object> raw = baseMapper.selectCountForSpecSync(qw);
if (raw == null) return stats;
stats.put("total", safeLong(raw, "total"));
stats.put("synced", safeLong(raw, "synced"));
stats.put("unsynced", safeLong(raw, "unsynced"));
stats.put("movedOn", safeLong(raw, "movedOn"));
return stats;
}
private long safeLong(Map<String, Object> map, String key) {
Object v = map.get(key);
if (v == null) return 0L;
try { return Long.parseLong(v.toString()); } catch (NumberFormatException e) { return 0L; }
}
private QueryWrapper<WmsMaterialCoil> buildProcessedCoilQw(java.util.Collection<Long> coilIds,
String enterCoilNo, String currentCoilNo, String material, String qualityStatus,
String syncStatus, java.util.Set<Long> filterSpecIds) {
QueryWrapper<WmsMaterialCoil> qw = new QueryWrapper<>();
// 不过滤 data_typedata_type=0已流转/历史)和 data_type=1当前均展示
// movedOn 状态仅作页面标记,不阻断规程绑定
qw.in("mc.coil_id", coilIds).eq("mc.del_flag", 0);
if (StringUtils.isNotBlank(enterCoilNo)) qw.like("mc.enter_coil_no", enterCoilNo);
if (StringUtils.isNotBlank(currentCoilNo)) qw.like("mc.current_coil_no", currentCoilNo);
if (StringUtils.isNotBlank(qualityStatus)) qw.eq("mc.quality_status", qualityStatus);
if (StringUtils.isNotBlank(material)) {
qw.apply("LOWER(CASE WHEN mc.item_type = 'raw_material' THEN COALESCE(rm.material,'') "
+ "ELSE COALESCE(p.material,'') END) LIKE {0}", "%" + material.toLowerCase() + "%");
}
if (filterSpecIds != null && !filterSpecIds.isEmpty()) qw.in("mc.spec_id", filterSpecIds);
// 用 version_id 判断是否已绑规程,与控制层 coil.getVersionId()!=null 的逻辑保持一致
// spec_id 有时可能为空(老数据只写了 version_id用 version_id 更可靠
if ("synced".equals(syncStatus)) qw.isNotNull("mc.version_id");
if ("unsynced".equals(syncStatus)) qw.isNull("mc.version_id");
return qw;
}
@Override
public String queryQualityStatusByWarehouseIdAndCurrentCoilNo(Long warehouseId, String currentCoilNo) {
if (warehouseId == null || StringUtils.isBlank(currentCoilNo)) {

View File

@@ -24,8 +24,12 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 规程版本Service实现
@@ -139,6 +143,135 @@ public class WmsProcessSpecVersionServiceImpl implements IWmsProcessSpecVersionS
return baseMapper.updateById(one) > 0;
}
@Override
public WmsProcessSpecVersionVo matchBestVersion(BigDecimal entryThick, BigDecimal exitThick,
BigDecimal entryWidth, BigDecimal exitWidth,
String grade, Long lineId) {
LambdaQueryWrapper<WmsProcessSpecVersion> lqw = Wrappers.lambdaQuery();
lqw.eq(WmsProcessSpecVersion::getIsActive, 1);
List<WmsProcessSpecVersionVo> versions = baseMapper.selectVoList(lqw);
if (versions.isEmpty()) {
return null;
}
// 按产线ID过滤只匹配属于指定产线的规程版本
if (lineId != null) {
List<Long> specIds = versions.stream()
.map(WmsProcessSpecVersionVo::getSpecId).distinct().collect(Collectors.toList());
LambdaQueryWrapper<WmsProcessSpec> slqw = Wrappers.lambdaQuery();
slqw.in(WmsProcessSpec::getSpecId, specIds);
slqw.eq(WmsProcessSpec::getLineId, lineId);
Set<Long> validSpecIds = wmsProcessSpecMapper.selectList(slqw)
.stream().map(WmsProcessSpec::getSpecId).collect(Collectors.toSet());
versions = versions.stream()
.filter(v -> validSpecIds.contains(v.getSpecId())).collect(Collectors.toList());
if (versions.isEmpty()) {
return null;
}
}
WmsProcessSpecVersionVo best = null;
int bestScore = -1;
for (WmsProcessSpecVersionVo v : versions) {
int score = 0;
if (entryThick != null && v.getMatchEntryThickMin() != null && v.getMatchEntryThickMax() != null
&& entryThick.compareTo(v.getMatchEntryThickMin()) >= 0
&& entryThick.compareTo(v.getMatchEntryThickMax()) <= 0) {
score++;
}
if (exitThick != null && v.getMatchExitThickMin() != null && v.getMatchExitThickMax() != null
&& exitThick.compareTo(v.getMatchExitThickMin()) >= 0
&& exitThick.compareTo(v.getMatchExitThickMax()) <= 0) {
score++;
}
if (entryWidth != null && v.getMatchEntryWidthMin() != null && v.getMatchEntryWidthMax() != null
&& entryWidth.compareTo(v.getMatchEntryWidthMin()) >= 0
&& entryWidth.compareTo(v.getMatchEntryWidthMax()) <= 0) {
score++;
}
if (exitWidth != null && v.getMatchExitWidthMin() != null && v.getMatchExitWidthMax() != null
&& exitWidth.compareTo(v.getMatchExitWidthMin()) >= 0
&& exitWidth.compareTo(v.getMatchExitWidthMax()) <= 0) {
score++;
}
if (StringUtils.isNotBlank(grade) && StringUtils.isNotBlank(v.getMatchSteelGrade())
&& grade.toLowerCase().contains(v.getMatchSteelGrade().toLowerCase())) {
score++;
}
if (score > bestScore) {
bestScore = score;
best = v;
}
}
if (best == null || bestScore == 0) {
return null;
}
WmsProcessSpec spec = wmsProcessSpecMapper.selectById(best.getSpecId());
if (spec != null) {
best.setSpecCode(spec.getSpecCode());
best.setSpecName(spec.getSpecName());
}
return best;
}
@Override
public List<WmsProcessSpecVersionVo> queryActiveVersionsEnriched(Long lineId) {
LambdaQueryWrapper<WmsProcessSpecVersion> lqw = Wrappers.lambdaQuery();
lqw.eq(WmsProcessSpecVersion::getIsActive, 1);
List<WmsProcessSpecVersionVo> versions = baseMapper.selectVoList(lqw);
if (versions.isEmpty()) {
return versions;
}
if (lineId != null) {
List<Long> specIds = versions.stream()
.map(WmsProcessSpecVersionVo::getSpecId).distinct().collect(Collectors.toList());
LambdaQueryWrapper<WmsProcessSpec> slqw = Wrappers.lambdaQuery();
slqw.in(WmsProcessSpec::getSpecId, specIds);
slqw.eq(WmsProcessSpec::getLineId, lineId);
Set<Long> validSpecIds = wmsProcessSpecMapper.selectList(slqw)
.stream().map(WmsProcessSpec::getSpecId).collect(Collectors.toSet());
versions = versions.stream()
.filter(v -> validSpecIds.contains(v.getSpecId())).collect(Collectors.toList());
if (versions.isEmpty()) {
return versions;
}
}
enrichVersionsWithSpec(versions);
return versions;
}
@Override
public List<WmsProcessSpecVersionVo> queryAllVersionsEnriched() {
// 不过滤 isActive获取全部版本含历史版本用于展示已绑定规程名称
List<WmsProcessSpecVersionVo> versions = baseMapper.selectVoList(Wrappers.lambdaQuery());
if (versions.isEmpty()) return versions;
enrichVersionsWithSpec(versions);
return versions;
}
/** 批量填充 specCode / specName / lineId公共逻辑 */
private void enrichVersionsWithSpec(List<WmsProcessSpecVersionVo> versions) {
List<Long> specIds = versions.stream()
.map(WmsProcessSpecVersionVo::getSpecId).distinct().collect(Collectors.toList());
LambdaQueryWrapper<WmsProcessSpec> sq = Wrappers.lambdaQuery();
sq.in(WmsProcessSpec::getSpecId, specIds);
Map<Long, WmsProcessSpec> specMap = wmsProcessSpecMapper.selectList(sq).stream()
.collect(Collectors.toMap(WmsProcessSpec::getSpecId, s -> s, (a, b) -> a));
for (WmsProcessSpecVersionVo v : versions) {
WmsProcessSpec spec = specMap.get(v.getSpecId());
if (spec != null) {
v.setSpecCode(spec.getSpecCode());
v.setSpecName(spec.getSpecName());
v.setLineId(spec.getLineId());
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {