原材料送检记录

This commit is contained in:
2026-05-18 16:59:34 +08:00
parent 5800b6b61c
commit a1181e49fc
19 changed files with 1182 additions and 1 deletions

View File

@@ -12,8 +12,12 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.oConvertUtils;
@@ -32,6 +36,8 @@ import org.jeecg.modules.print.support.PrintServerPdfJobService;
import org.jeecg.modules.print.util.PrintBizDataMappingUtil;
import org.jeecg.modules.xslmes.constant.MesXslPrintConstants;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecord;
import org.jeecg.modules.xslmes.mapper.MesXslRawMaterialInspectRecordMapper;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -72,6 +78,8 @@ public class MesXslRawMaterialCardController extends JeecgController<MesXslRawMa
private IPrintTemplateService printTemplateService;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private MesXslRawMaterialInspectRecordMapper inspectRecordMapper;
/**
* 分页列表查询
@@ -82,8 +90,11 @@ public class MesXslRawMaterialCardController extends JeecgController<MesXslRawMa
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
if (mesXslRawMaterialCard == null) {
mesXslRawMaterialCard = new MesXslRawMaterialCard();
}
// 库区条件:去掉实体上的值避免 QueryGenerator 再拼一班;用 TRIM 与看板聚合一致(避免首尾空格导致「有汇总无明细」)
String rawWarehouseArea = mesXslRawMaterialCard != null ? mesXslRawMaterialCard.getWarehouseArea() : null;
String rawWarehouseArea = mesXslRawMaterialCard.getWarehouseArea();
String areaEq = oConvertUtils.isNotEmpty(rawWarehouseArea) ? rawWarehouseArea.trim() : "";
boolean filterByWarehouseArea = !areaEq.isEmpty();
if (filterByWarehouseArea) {
@@ -114,9 +125,34 @@ public class MesXslRawMaterialCardController extends JeecgController<MesXslRawMa
}
Page<MesXslRawMaterialCard> page = new Page<>(pageNo, pageSize);
IPage<MesXslRawMaterialCard> pageList = mesXslRawMaterialCardService.page(page, queryWrapper);
fillPendingInspectFlag(pageList.getRecords());
return Result.OK(pageList);
}
private void fillPendingInspectFlag(List<MesXslRawMaterialCard> cards) {
if (cards == null || cards.isEmpty()) {
return;
}
Set<String> cardIds = cards.stream()
.map(MesXslRawMaterialCard::getId)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
if (cardIds.isEmpty()) {
return;
}
List<MesXslRawMaterialInspectRecord> pendingList = inspectRecordMapper.selectList(
new QueryWrapper<MesXslRawMaterialInspectRecord>()
.select("raw_material_card_id")
.in("raw_material_card_id", cardIds)
.eq("inspect_status", "0")
.groupBy("raw_material_card_id"));
Set<String> pendingCardIds = pendingList == null ? Collections.emptySet() : pendingList.stream()
.map(MesXslRawMaterialInspectRecord::getRawMaterialCardId)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
cards.forEach(card -> card.setHasPendingInspect(pendingCardIds.contains(card.getId())));
}
/**
* 添加
*/

View File

@@ -0,0 +1,115 @@
package org.jeecg.modules.xslmes.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecord;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecordLine;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialInspectRecordService;
import org.jeecg.modules.xslmes.vo.MesXslRawMaterialInspectRecordPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
@Tag(name = "原材料送检记录")
@RestController
@RequestMapping("/xslmes/mesXslRawMaterialInspectRecord")
public class MesXslRawMaterialInspectRecordController
extends JeecgController<MesXslRawMaterialInspectRecord, IMesXslRawMaterialInspectRecordService> {
@Autowired private IMesXslRawMaterialInspectRecordService inspectRecordService;
@Operation(summary = "原材料送检记录-分页列表查询")
@GetMapping("/list")
public Result<IPage<MesXslRawMaterialInspectRecord>> queryPageList(
MesXslRawMaterialInspectRecord query,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslRawMaterialInspectRecord> queryWrapper =
QueryGenerator.initQueryWrapper(query, req.getParameterMap());
queryWrapper.orderByDesc("inspect_time");
IPage<MesXslRawMaterialInspectRecord> pageList =
inspectRecordService.page(new Page<>(pageNo, pageSize), queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "原材料送检记录-送检")
@Operation(summary = "原材料送检记录-送检(由原材料卡片生成)")
@RequiresPermissions("xslmes:mes_xsl_raw_material_card:edit")
@PostMapping("/createByCard")
public Result<MesXslRawMaterialInspectRecord> createByCard(@RequestBody Map<String, Object> body) {
String rawMaterialCardId =
body.get("rawMaterialCardId") == null ? "" : body.get("rawMaterialCardId").toString();
if (StringUtils.isBlank(rawMaterialCardId)) {
return Result.error("rawMaterialCardId不能为空");
}
MesXslRawMaterialInspectRecord record =
inspectRecordService.createByRawMaterialCardId(rawMaterialCardId.trim());
return Result.OK("送检成功", record);
}
@Operation(summary = "原材料送检记录-通过id查询")
@GetMapping("/queryById")
public Result<MesXslRawMaterialInspectRecord> queryById(@RequestParam(name = "id") String id) {
MesXslRawMaterialInspectRecord db = inspectRecordService.getById(id);
if (db == null) {
return Result.error("未找到对应数据");
}
return Result.OK(db);
}
@Operation(summary = "原材料送检记录-按主表查询子表")
@GetMapping("/queryLineListByRecordId")
public Result<List<MesXslRawMaterialInspectRecordLine>> queryLineListByRecordId(
@RequestParam(name = "id") String id) {
return Result.OK(inspectRecordService.selectLinesByRecordId(id));
}
@AutoLog(value = "原材料送检记录-录入检验结果前加载明细")
@Operation(summary = "原材料送检记录-录入检验结果前加载明细")
@RequiresPermissions("xslmes:mes_xsl_raw_material_inspect_record:edit")
@PostMapping("/prepareResultEntry")
public Result<List<MesXslRawMaterialInspectRecordLine>> prepareResultEntry(
@RequestBody Map<String, Object> body) {
String id = body.get("id") == null ? "" : body.get("id").toString();
if (StringUtils.isBlank(id)) {
return Result.error("id不能为空");
}
return Result.OK(inspectRecordService.prepareResultEntryLines(id.trim()));
}
@AutoLog(value = "原材料送检记录-保存检验结果")
@Operation(summary = "原材料送检记录-保存检验结果")
@RequiresPermissions("xslmes:mes_xsl_raw_material_inspect_record:edit")
@PostMapping("/saveInspectResult")
public Result<String> saveInspectResult(@RequestBody MesXslRawMaterialInspectRecordPage page) {
if (StringUtils.isBlank(page.getId())) {
return Result.error("id不能为空");
}
inspectRecordService.saveInspectResult(page.getId(), page.getLineList());
return Result.OK("保存成功");
}
@RequiresPermissions("xslmes:mes_xsl_raw_material_inspect_record:exportXls")
@RequestMapping("/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslRawMaterialInspectRecord query) {
return super.exportXls(request, query, MesXslRawMaterialInspectRecord.class, "原材料送检记录");
}
}

View File

@@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.Date;
import java.math.BigDecimal;
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;
@@ -138,4 +139,8 @@ public class MesXslRawMaterialCard implements Serializable {
@Schema(description = "租户ID")
private Integer tenantId;
@TableField(exist = false)
@Schema(description = "是否存在待检送检记录(前端控制送检按钮显隐)")
private Boolean hasPendingInspect;
}

View File

@@ -0,0 +1,91 @@
package org.jeecg.modules.xslmes.entity;
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 com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
@Data
@TableName("mes_xsl_raw_material_inspect_record")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description = "原材料送检记录")
public class MesXslRawMaterialInspectRecord implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private String id;
@Schema(description = "原材料卡片ID")
private String rawMaterialCardId;
@Excel(name = "条码", width = 20)
@Schema(description = "条码")
private String barcode;
@Excel(name = "批次号", width = 20)
@Schema(description = "批次号")
private String batchNo;
@Schema(description = "物料ID")
private String materialId;
@Excel(name = "物料名称", width = 20)
@Schema(description = "物料名称")
private String materialName;
@Excel(name = "检验状态", width = 12, dicCode = "xslmes_inspect_status")
@Dict(dicCode = "xslmes_inspect_status")
@Schema(description = "检验状态xslmes_inspect_status0待检 1合格 2不合格")
private String inspectStatus;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "送检时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "送检时间")
private Date inspectTime;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "判定时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "判定时间")
private Date resultTime;
@Schema(description = "备注")
private String remark;
@Schema(description = "创建人")
private String createBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建时间")
private Date createTime;
@Schema(description = "更新人")
private String updateBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "更新时间")
private Date updateTime;
@Schema(description = "租户ID")
private Integer tenantId;
@TableField(exist = false)
@Schema(description = "送检明细")
private List<MesXslRawMaterialInspectRecordLine> lineList;
}

View File

@@ -0,0 +1,73 @@
package org.jeecg.modules.xslmes.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.springframework.format.annotation.DateTimeFormat;
@Data
@TableName("mes_xsl_raw_material_inspect_record_line")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description = "原材料送检记录-检验明细")
public class MesXslRawMaterialInspectRecordLine implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
private String id;
@Schema(description = "送检记录主表ID")
private String recordId;
@Schema(description = "检验标准ID")
private String inspectStdId;
@Schema(description = "检验项目ID")
private String inspectItemId;
@Schema(description = "检验项目名称")
private String inspectItemName;
@Schema(description = "容许最小值")
private BigDecimal allowMin;
@Schema(description = "包含最小值 1是 0否")
private Integer includeMinFlag;
@Schema(description = "容许最大值")
private BigDecimal allowMax;
@Schema(description = "包含最大值 1是 0否")
private Integer includeMaxFlag;
@Schema(description = "检验值")
private BigDecimal inspectValue;
@Dict(dicCode = "xslmes_inspect_status")
@Schema(description = "明细判定状态xslmes_inspect_status0待检 1合格 2不合格")
private String passFlag;
@Schema(description = "排序")
private Integer sortNo;
private String createBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
private String updateBy;
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
}

View File

@@ -0,0 +1,7 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecordLine;
public interface MesXslRawMaterialInspectRecordLineMapper
extends BaseMapper<MesXslRawMaterialInspectRecordLine> {}

View File

@@ -0,0 +1,7 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecord;
public interface MesXslRawMaterialInspectRecordMapper
extends BaseMapper<MesXslRawMaterialInspectRecord> {}

View File

@@ -0,0 +1,26 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import java.math.BigDecimal;
import java.util.List;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecord;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecordLine;
public interface IMesXslRawMaterialInspectRecordService
extends IService<MesXslRawMaterialInspectRecord> {
MesXslRawMaterialInspectRecord createByRawMaterialCardId(String rawMaterialCardId);
List<MesXslRawMaterialInspectRecordLine> selectLinesByRecordId(String recordId);
List<MesXslRawMaterialInspectRecordLine> prepareResultEntryLines(String recordId);
void saveInspectResult(String recordId, List<MesXslRawMaterialInspectRecordLine> lineList);
String evaluatePassFlag(
BigDecimal inspectValue,
BigDecimal allowMin,
Integer includeMinFlag,
BigDecimal allowMax,
Integer includeMaxFlag);
}

View File

@@ -0,0 +1,302 @@
package org.jeecg.modules.xslmes.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.mes.material.entity.MesMaterial;
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
import org.jeecg.modules.mes.material.entity.MesRawMaterialInspectStd;
import org.jeecg.modules.mes.material.entity.MesRawMaterialInspectStdLine;
import org.jeecg.modules.mes.material.mapper.MesMaterialMapper;
import org.jeecg.modules.mes.material.mapper.MesMixerMaterialMapper;
import org.jeecg.modules.mes.material.mapper.MesRawMaterialInspectStdLineMapper;
import org.jeecg.modules.mes.material.mapper.MesRawMaterialInspectStdMapper;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecord;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecordLine;
import org.jeecg.modules.xslmes.mapper.MesXslRawMaterialInspectRecordLineMapper;
import org.jeecg.modules.xslmes.mapper.MesXslRawMaterialInspectRecordMapper;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialInspectRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Slf4j
public class MesXslRawMaterialInspectRecordServiceImpl
extends ServiceImpl<MesXslRawMaterialInspectRecordMapper, MesXslRawMaterialInspectRecord>
implements IMesXslRawMaterialInspectRecordService {
private static final String CARD_TEST_RESULT_UNTESTED = "0";
private static final String CARD_TEST_RESULT_PASS = "1";
private static final String CARD_TEST_RESULT_FAIL = "2";
private static final String STATUS_PENDING = "0";
private static final String STATUS_PASS = "1";
private static final String STATUS_FAIL = "2";
@Autowired private IMesXslRawMaterialCardService rawMaterialCardService;
@Autowired private MesXslRawMaterialInspectRecordLineMapper recordLineMapper;
@Autowired private MesMaterialMapper mesMaterialMapper;
@Autowired private MesMixerMaterialMapper mesMixerMaterialMapper;
@Autowired private MesRawMaterialInspectStdMapper inspectStdMapper;
@Autowired private MesRawMaterialInspectStdLineMapper inspectStdLineMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public MesXslRawMaterialInspectRecord createByRawMaterialCardId(String rawMaterialCardId) {
MesXslRawMaterialCard card = rawMaterialCardService.getById(rawMaterialCardId);
if (card == null) {
throw new JeecgBootException("未找到原材料卡片");
}
long pendingCount =
this.lambdaQuery()
.eq(MesXslRawMaterialInspectRecord::getRawMaterialCardId, rawMaterialCardId)
.eq(MesXslRawMaterialInspectRecord::getInspectStatus, STATUS_PENDING)
.count();
if (pendingCount > 0) {
throw new JeecgBootException("该原材料卡片已存在待检送检记录,不能重复送检");
}
String cardTestResult = normalize(card.getTestResult());
if (StringUtils.isNotBlank(cardTestResult) && !CARD_TEST_RESULT_UNTESTED.equals(cardTestResult)) {
throw new JeecgBootException("仅未检状态的原材料卡片允许送检");
}
MesXslRawMaterialInspectRecord entity = new MesXslRawMaterialInspectRecord();
entity.setRawMaterialCardId(card.getId());
entity.setBarcode(card.getBarcode());
entity.setBatchNo(card.getBatchNo());
entity.setMaterialId(card.getMaterialId());
entity.setMaterialName(card.getMaterialName());
entity.setInspectStatus(STATUS_PENDING);
entity.setInspectTime(new Date());
this.save(entity);
// 送检后将卡片检测结果置为待检
MesXslRawMaterialCard updateCard = new MesXslRawMaterialCard();
updateCard.setId(card.getId());
updateCard.setTestResult(CARD_TEST_RESULT_UNTESTED);
rawMaterialCardService.updateById(updateCard);
return entity;
}
@Override
public List<MesXslRawMaterialInspectRecordLine> selectLinesByRecordId(String recordId) {
return recordLineMapper.selectList(
new LambdaQueryWrapper<MesXslRawMaterialInspectRecordLine>()
.eq(MesXslRawMaterialInspectRecordLine::getRecordId, recordId)
.orderByAsc(MesXslRawMaterialInspectRecordLine::getSortNo));
}
@Override
@Transactional(rollbackFor = Exception.class)
public List<MesXslRawMaterialInspectRecordLine> prepareResultEntryLines(String recordId) {
MesXslRawMaterialInspectRecord record = this.getById(recordId);
if (record == null) {
throw new JeecgBootException("送检记录不存在");
}
List<MesXslRawMaterialInspectRecordLine> current = selectLinesByRecordId(recordId);
if (!current.isEmpty()) {
return current;
}
MesRawMaterialInspectStd std = resolveEnableInspectStd(record.getMaterialId(), record.getMaterialName());
if (std == null) {
throw new JeecgBootException("未找到已启用的原材料检验标准,请先维护并启用检验标准");
}
List<MesRawMaterialInspectStdLine> stdLines =
inspectStdLineMapper.selectList(
new LambdaQueryWrapper<MesRawMaterialInspectStdLine>()
.eq(MesRawMaterialInspectStdLine::getStdId, std.getId())
.orderByAsc(MesRawMaterialInspectStdLine::getSortNo));
if (stdLines.isEmpty()) {
throw new JeecgBootException("当前检验标准未配置明细检验项目");
}
int sortNo = 0;
List<MesXslRawMaterialInspectRecordLine> out = new ArrayList<>(stdLines.size());
for (MesRawMaterialInspectStdLine stdLine : stdLines) {
MesXslRawMaterialInspectRecordLine line = new MesXslRawMaterialInspectRecordLine();
line.setRecordId(recordId);
line.setInspectStdId(std.getId());
line.setInspectItemId(stdLine.getInspectItemId());
line.setInspectItemName(stdLine.getInspectItemName());
line.setAllowMin(stdLine.getAllowMin());
line.setIncludeMinFlag(stdLine.getIncludeMinFlag() == null ? 0 : stdLine.getIncludeMinFlag());
line.setAllowMax(stdLine.getAllowMax());
line.setIncludeMaxFlag(stdLine.getIncludeMaxFlag() == null ? 0 : stdLine.getIncludeMaxFlag());
line.setPassFlag(STATUS_PENDING);
line.setSortNo(sortNo++);
recordLineMapper.insert(line);
out.add(line);
}
return out;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveInspectResult(String recordId, List<MesXslRawMaterialInspectRecordLine> lineList) {
MesXslRawMaterialInspectRecord record = this.getById(recordId);
if (record == null) {
throw new JeecgBootException("送检记录不存在");
}
if (lineList == null || lineList.isEmpty()) {
throw new JeecgBootException("请至少录入一条检验结果");
}
boolean allPass = true;
for (MesXslRawMaterialInspectRecordLine line : lineList) {
if (StringUtils.isBlank(line.getId())) {
throw new JeecgBootException("明细ID不能为空请刷新后重试");
}
MesXslRawMaterialInspectRecordLine dbLine = recordLineMapper.selectById(line.getId());
if (dbLine == null || !recordId.equals(dbLine.getRecordId())) {
throw new JeecgBootException("明细不存在或不属于当前送检记录");
}
String passFlag =
evaluatePassFlag(
line.getInspectValue(),
dbLine.getAllowMin(),
dbLine.getIncludeMinFlag(),
dbLine.getAllowMax(),
dbLine.getIncludeMaxFlag());
dbLine.setInspectValue(line.getInspectValue());
dbLine.setPassFlag(passFlag);
recordLineMapper.updateById(dbLine);
if (!STATUS_PASS.equals(passFlag)) {
allPass = false;
}
}
record.setInspectStatus(allPass ? STATUS_PASS : STATUS_FAIL);
record.setResultTime(new Date());
this.updateById(record);
// 判定完成后回写原材料卡片检测结果
if (StringUtils.isNotBlank(record.getRawMaterialCardId())) {
MesXslRawMaterialCard card = new MesXslRawMaterialCard();
card.setId(record.getRawMaterialCardId());
card.setTestResult(allPass ? CARD_TEST_RESULT_PASS : CARD_TEST_RESULT_FAIL);
rawMaterialCardService.updateById(card);
}
}
@Override
public String evaluatePassFlag(
BigDecimal inspectValue,
BigDecimal allowMin,
Integer includeMinFlag,
BigDecimal allowMax,
Integer includeMaxFlag) {
if (inspectValue == null) {
return STATUS_FAIL;
}
if (allowMin != null) {
int cmpMin = inspectValue.compareTo(allowMin);
boolean includeMin = includeMinFlag != null && includeMinFlag == 1;
if (includeMin ? cmpMin < 0 : cmpMin <= 0) {
return STATUS_FAIL;
}
}
if (allowMax != null) {
int cmpMax = inspectValue.compareTo(allowMax);
boolean includeMax = includeMaxFlag != null && includeMaxFlag == 1;
if (includeMax ? cmpMax > 0 : cmpMax >= 0) {
return STATUS_FAIL;
}
}
return STATUS_PASS;
}
private MesRawMaterialInspectStd resolveEnableInspectStd(String materialId, String materialName) {
String normalizedMaterialId = normalize(materialId);
if (StringUtils.isBlank(normalizedMaterialId)) {
log.warn("送检标准匹配失败送检记录物料ID为空materialName={}", materialName);
return null;
}
List<MesRawMaterialInspectStd> allStds =
inspectStdMapper.selectList(
new LambdaQueryWrapper<MesRawMaterialInspectStd>()
.and(
w ->
w.eq(MesRawMaterialInspectStd::getDelFlag, 0)
.or()
.isNull(MesRawMaterialInspectStd::getDelFlag))
.orderByDesc(MesRawMaterialInspectStd::getEnableFlag)
.orderByDesc(MesRawMaterialInspectStd::getEffectiveDate)
.orderByDesc(MesRawMaterialInspectStd::getCreateTime));
if (allStds.isEmpty()) {
log.warn("送检标准匹配失败没有可用检验标准materialId={}", materialId);
return null;
}
String mappedMixerMaterialId = mapMaterialIdToMixerMaterialId(normalizedMaterialId);
// 第一优先级:仅在启用标准中匹配
MesRawMaterialInspectStd matchedEnabled = matchByMaterialId(allStds, normalizedMaterialId, mappedMixerMaterialId, true);
if (matchedEnabled != null) {
return matchedEnabled;
}
// 第二优先级:若未启用标准,则回退到同物料最新标准(避免业务无法录入)
MesRawMaterialInspectStd matchedAny = matchByMaterialId(allStds, normalizedMaterialId, mappedMixerMaterialId, false);
if (matchedAny != null) {
log.warn(
"送检标准未找到启用版本,已回退到未启用标准 stdId={}, materialId={}, mappedMixerMaterialId={}, enableFlag={}",
matchedAny.getId(),
materialId,
mappedMixerMaterialId,
matchedAny.getEnableFlag());
return matchedAny;
}
log.warn(
"送检标准匹配失败仅物料ID匹配materialId={}, mappedMixerMaterialId={}, materialName={}, stdCount={}",
materialId,
mappedMixerMaterialId,
materialName,
allStds.size());
return null;
}
private MesRawMaterialInspectStd matchByMaterialId(
List<MesRawMaterialInspectStd> standards,
String normalizedMaterialId,
String mappedMixerMaterialId,
boolean onlyEnabled) {
for (MesRawMaterialInspectStd std : standards) {
if (onlyEnabled && !Objects.equals(std.getEnableFlag(), 1)) {
continue;
}
String stdMaterialId = normalize(std.getMixerMaterialId());
if (Objects.equals(normalizedMaterialId, stdMaterialId)) {
return std;
}
if (StringUtils.isNotBlank(mappedMixerMaterialId) && Objects.equals(mappedMixerMaterialId, stdMaterialId)) {
return std;
}
}
return null;
}
private String mapMaterialIdToMixerMaterialId(String materialId) {
MesMaterial material = mesMaterialMapper.selectById(materialId);
if (material == null || StringUtils.isBlank(material.getMaterialCode())) {
return null;
}
MesMixerMaterial mixerMaterial =
mesMixerMaterialMapper.selectOne(
new LambdaQueryWrapper<MesMixerMaterial>()
.eq(MesMixerMaterial::getMaterialCode, StringUtils.trimToEmpty(material.getMaterialCode()))
.last("LIMIT 1"));
return mixerMaterial == null ? null : normalize(mixerMaterial.getId());
}
private String normalize(String value) {
return StringUtils.trimToEmpty(value);
}
}

View File

@@ -0,0 +1,10 @@
package org.jeecg.modules.xslmes.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInspectRecord;
/** 原材料送检记录主子表保存页。 */
@Data
@EqualsAndHashCode(callSuper = true)
public class MesXslRawMaterialInspectRecordPage extends MesXslRawMaterialInspectRecord {}