原材料送检记录

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

@@ -0,0 +1,66 @@
-- 原材料送检记录菜单与权限挂到 MES管理
SET NAMES utf8mb4;
SET @mes_parent_id = (
SELECT id
FROM sys_permission
WHERE url = '/mes' AND menu_type = 0
ORDER BY create_time ASC
LIMIT 1
);
SET @mes_parent_id = IFNULL(@mes_parent_id, '1860000000000000001');
-- 二级菜单原材料送检记录
INSERT INTO sys_permission(
id, parent_id, name, url, component, component_name, menu_type, perms, perms_type, sort_no,
is_route, is_leaf, hidden, status, del_flag, keep_alive, internal_or_external, create_by, create_time
)
VALUES (
'1860000000000099111', @mes_parent_id, '原材料送检记录',
'/xslmes/mesXslRawMaterialInspectRecordList',
'xslmes/mesXslRawMaterialInspectRecord/MesXslRawMaterialInspectRecordList',
'MesXslRawMaterialInspectRecordList', 1, NULL, '1', 22,
1, 1, 0, '1', 0, 1, 0, 'admin', NOW()
)
ON DUPLICATE KEY UPDATE
parent_id = VALUES(parent_id),
name = VALUES(name),
url = VALUES(url),
component = VALUES(component),
component_name = VALUES(component_name),
menu_type = VALUES(menu_type),
perms = VALUES(perms),
perms_type = VALUES(perms_type),
sort_no = VALUES(sort_no),
is_route = VALUES(is_route),
is_leaf = VALUES(is_leaf),
hidden = VALUES(hidden),
status = VALUES(status),
del_flag = VALUES(del_flag),
keep_alive = VALUES(keep_alive),
internal_or_external = VALUES(internal_or_external);
-- 按钮权限
INSERT INTO sys_permission(id, parent_id, name, menu_type, perms, perms_type, status, del_flag, create_by, create_time) VALUES
('1860000000000099112', '1860000000000099111', '编辑', 2, 'xslmes:mes_xsl_raw_material_inspect_record:edit', '1', '1', 0, 'admin', NOW()),
('1860000000000099113', '1860000000000099111', '导出', 2, 'xslmes:mes_xsl_raw_material_inspect_record:exportXls', '1', '1', 0, 'admin', NOW())
ON DUPLICATE KEY UPDATE
parent_id = VALUES(parent_id),
name = VALUES(name),
menu_type = VALUES(menu_type),
perms = VALUES(perms),
perms_type = VALUES(perms_type),
status = VALUES(status),
del_flag = VALUES(del_flag);
-- admin 角色授权
INSERT INTO sys_role_permission(id, role_id, permission_id, operate_date, operate_ip)
SELECT REPLACE(UUID(), '-', ''), 'f6817f48af4fb3af11b9e8bf182f618b', p.id, NOW(), '127.0.0.1'
FROM sys_permission p
WHERE p.id IN ('1860000000000099111', '1860000000000099112', '1860000000000099113')
AND NOT EXISTS (
SELECT 1
FROM sys_role_permission rp
WHERE rp.role_id = 'f6817f48af4fb3af11b9e8bf182f618b'
AND rp.permission_id = p.id
);

View File

@@ -0,0 +1,36 @@
-- 原材料送检记录测试数据重置脚本稳妥版
-- 作用
-- 1) 将存在送检记录关联的原材料卡片检测结果重置为未检(0)
-- 2) 清空原材料送检记录主表/子表数据
SET NAMES utf8mb4;
START TRANSACTION;
-- 执行前计数便于确认是否命中数据
SELECT COUNT(1) AS before_record_count FROM mes_xsl_raw_material_inspect_record;
SELECT COUNT(1) AS before_record_line_count FROM mes_xsl_raw_material_inspect_record_line;
-- 回写原材料卡片检测结果为未检0只重置存在送检记录关联的卡片
UPDATE mes_xsl_raw_material_card c
JOIN (
SELECT DISTINCT r.raw_material_card_id AS card_id
FROM mes_xsl_raw_material_inspect_record r
WHERE r.raw_material_card_id IS NOT NULL
AND r.raw_material_card_id <> ''
) t ON t.card_id = c.id
SET c.test_result = '0',
c.update_time = NOW();
-- 先删子表再删主表
DELETE FROM mes_xsl_raw_material_inspect_record_line
WHERE record_id IN (
SELECT id FROM mes_xsl_raw_material_inspect_record
);
DELETE FROM mes_xsl_raw_material_inspect_record;
COMMIT;
-- 执行后计数
SELECT COUNT(1) AS remaining_record_count FROM mes_xsl_raw_material_inspect_record;
SELECT COUNT(1) AS remaining_record_line_count FROM mes_xsl_raw_material_inspect_record_line;

View File

@@ -0,0 +1,80 @@
-- 原材料送检记录主表 + 子表
SET NAMES utf8mb4;
CREATE TABLE IF NOT EXISTS `mes_xsl_raw_material_inspect_record` (
`id` varchar(32) NOT NULL COMMENT '主键',
`raw_material_card_id` varchar(32) DEFAULT NULL COMMENT '原材料卡片ID',
`barcode` varchar(128) DEFAULT NULL COMMENT '条码',
`batch_no` varchar(128) DEFAULT NULL COMMENT '批次号',
`material_id` varchar(32) DEFAULT NULL COMMENT '物料ID',
`material_name` varchar(200) DEFAULT NULL COMMENT '物料名称',
`inspect_status` varchar(10) DEFAULT '0' COMMENT '检验状态字典 xslmes_inspect_status0待检 1合格 2不合格',
`inspect_time` datetime DEFAULT NULL COMMENT '送检时间',
`result_time` datetime DEFAULT NULL COMMENT '判定时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`create_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(32) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`tenant_id` int DEFAULT NULL COMMENT '租户',
PRIMARY KEY (`id`),
KEY `idx_xsl_rm_ir_card` (`raw_material_card_id`),
KEY `idx_xsl_rm_ir_status` (`inspect_status`),
KEY `idx_xsl_rm_ir_time` (`inspect_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='原材料送检记录';
CREATE TABLE IF NOT EXISTS `mes_xsl_raw_material_inspect_record_line` (
`id` varchar(32) NOT NULL COMMENT '主键',
`record_id` varchar(32) NOT NULL COMMENT '送检记录主表ID',
`inspect_std_id` varchar(32) DEFAULT NULL COMMENT '检验标准ID',
`inspect_item_id` varchar(32) DEFAULT NULL COMMENT '检验项目ID',
`inspect_item_name` varchar(200) DEFAULT NULL COMMENT '检验项目名称',
`allow_min` decimal(24,6) DEFAULT NULL COMMENT '容许最小值',
`include_min_flag` int NOT NULL DEFAULT '0' COMMENT '包含最小值1是 0否',
`allow_max` decimal(24,6) DEFAULT NULL COMMENT '容许最大值',
`include_max_flag` int NOT NULL DEFAULT '0' COMMENT '包含最大值1是 0否',
`inspect_value` decimal(24,6) DEFAULT NULL COMMENT '检验值',
`pass_flag` varchar(10) DEFAULT '0' COMMENT '判定状态字典 xslmes_inspect_status0待检 1合格 2不合格',
`sort_no` int DEFAULT NULL COMMENT '排序',
`create_by` varchar(32) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(32) DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_xsl_rm_irl_record` (`record_id`),
KEY `idx_xsl_rm_irl_item` (`inspect_item_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='原材料送检记录-检验明细';
-- 字典送检状态
INSERT INTO `sys_dict` (`id`, `dict_name`, `dict_code`, `description`, `del_flag`, `create_by`, `create_time`, `type`)
SELECT REPLACE(UUID(), '-', ''), '送检状态', 'xslmes_inspect_status', '原材料送检状态待检/合格/不合格', 0, 'admin', NOW(), 0
WHERE NOT EXISTS (
SELECT 1 FROM `sys_dict` WHERE `dict_code` = 'xslmes_inspect_status' AND `del_flag` = 0
);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '待检', '0', '待检', 1, 1, 'admin', NOW()
FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_inspect_status'
AND d.`del_flag` = 0
AND NOT EXISTS (
SELECT 1 FROM `sys_dict_item` i WHERE i.dict_id = d.id AND i.item_value = '0'
);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '合格', '1', '合格', 2, 1, 'admin', NOW()
FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_inspect_status'
AND d.`del_flag` = 0
AND NOT EXISTS (
SELECT 1 FROM `sys_dict_item` i WHERE i.dict_id = d.id AND i.item_value = '1'
);
INSERT INTO `sys_dict_item` (`id`, `dict_id`, `item_text`, `item_value`, `description`, `sort_order`, `status`, `create_by`, `create_time`)
SELECT REPLACE(UUID(), '-', ''), d.id, '不合格', '2', '不合格', 3, 1, 'admin', NOW()
FROM `sys_dict` d
WHERE d.`dict_code` = 'xslmes_inspect_status'
AND d.`del_flag` = 0
AND NOT EXISTS (
SELECT 1 FROM `sys_dict_item` i WHERE i.dict_id = d.id AND i.item_value = '2'
);

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 {}

View File

@@ -16,6 +16,7 @@ enum Api {
queryPrinters = '/xslmes/mesXslRawMaterialCard/queryPrinters',
prepareNativePrint = '/xslmes/mesXslRawMaterialCard/prepareNativePrint',
printPdf = '/xslmes/mesXslRawMaterialCard/printPdf',
createInspectRecordByCard = '/xslmes/mesXslRawMaterialInspectRecord/createByCard',
}
export const getExportUrl = Api.exportXls;
@@ -63,3 +64,6 @@ export const prepareNativePrint = (id: string) =>
/** id + 前端生成的 pdfBase64printerName 空则用默认队列 */
export const printPdf = (data: { id: string; printerName?: string; pdfBase64: string; fileName?: string }) =>
defHttp.post({ url: Api.printPdf, data, timeout: 3 * 60 * 1000 });
export const createInspectRecordByCard = (rawMaterialCardId: string) =>
defHttp.post({ url: Api.createInspectRecordByCard, params: { rawMaterialCardId } });

View File

@@ -99,6 +99,7 @@
getExportUrl,
updatePriority,
prepareNativePrint,
createInspectRecordByCard,
} from './MesXslRawMaterialCard.api';
import { useMessage } from '/@/hooks/web/useMessage';
import {
@@ -431,6 +432,14 @@
}
}
async function handleSendInspect(record: Recordable) {
await createInspectRecordByCard(record.id as string);
record.testResult = '0';
record.hasPendingInspect = true;
createMessage.success('已生成送检记录');
reload();
}
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
@@ -452,6 +461,12 @@
onClick: handlePrintRow.bind(null, record),
auth: 'xslmes:mes_xsl_raw_material_card:edit',
},
{
label: '送检',
onClick: handleSendInspect.bind(null, record),
auth: 'xslmes:mes_xsl_raw_material_card:edit',
ifShow: () => (!record.testResult || record.testResult === '0') && !record.hasPendingInspect,
},
];
}

View File

@@ -0,0 +1,17 @@
import { defHttp } from '/@/utils/http/axios';
enum Api {
list = '/xslmes/mesXslRawMaterialInspectRecord/list',
queryById = '/xslmes/mesXslRawMaterialInspectRecord/queryById',
queryLineListByRecordId = '/xslmes/mesXslRawMaterialInspectRecord/queryLineListByRecordId',
prepareResultEntry = '/xslmes/mesXslRawMaterialInspectRecord/prepareResultEntry',
saveInspectResult = '/xslmes/mesXslRawMaterialInspectRecord/saveInspectResult',
exportXls = '/xslmes/mesXslRawMaterialInspectRecord/exportXls',
}
export const getExportUrl = Api.exportXls;
export const list = (params) => defHttp.get({ url: Api.list, params });
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
export const queryLineListByRecordId = (params) => defHttp.get({ url: Api.queryLineListByRecordId, params });
export const prepareResultEntry = (id: string) => defHttp.post({ url: Api.prepareResultEntry, params: { id } });
export const saveInspectResult = (params) => defHttp.post({ url: Api.saveInspectResult, params });

View File

@@ -0,0 +1,80 @@
import { BasicColumn, FormSchema } from '/@/components/Table';
import { JVxeColumn, JVxeTypes } from '/@/components/jeecg/JVxeTable/types';
export const columns: BasicColumn[] = [
{ title: '条码', align: 'center', dataIndex: 'barcode', width: 180 },
{ title: '批次号', align: 'center', dataIndex: 'batchNo', width: 160 },
{ title: '物料名称', align: 'center', dataIndex: 'materialName', width: 180 },
{ title: '检验状态', align: 'center', dataIndex: 'inspectStatus_dictText', width: 120 },
{ title: '送检时间', align: 'center', dataIndex: 'inspectTime', width: 170 },
{ title: '判定时间', align: 'center', dataIndex: 'resultTime', width: 170 },
];
export const searchFormSchema: FormSchema[] = [
{ label: '条码', field: 'barcode', component: 'Input', colProps: { span: 6 } },
{ label: '批次号', field: 'batchNo', component: 'Input', colProps: { span: 6 } },
{ label: '物料名称', field: 'materialName', component: 'Input', colProps: { span: 6 } },
{
label: '检验状态',
field: 'inspectStatus',
component: 'JDictSelectTag',
componentProps: { dictCode: 'xslmes_inspect_status' },
colProps: { span: 6 },
},
];
export const lineJVxeColumns: JVxeColumn[] = [
{
title: '检验项目',
key: 'inspectItemName',
type: JVxeTypes.input,
width: 220,
disabled: true,
},
{
title: '容许最小值',
key: 'allowMin',
type: JVxeTypes.inputNumber,
width: 120,
disabled: true,
},
{
title: '包含最小值',
key: 'includeMinFlag',
type: JVxeTypes.checkbox,
width: 110,
align: 'center',
customValue: [1, 0],
disabled: true,
},
{
title: '容许最大值',
key: 'allowMax',
type: JVxeTypes.inputNumber,
width: 120,
disabled: true,
},
{
title: '包含最大值',
key: 'includeMaxFlag',
type: JVxeTypes.checkbox,
width: 110,
align: 'center',
customValue: [1, 0],
disabled: true,
},
{
title: '检验值',
key: 'inspectValue',
type: JVxeTypes.inputNumber,
width: 120,
validateRules: [{ required: true, message: '${title}必填' }],
},
{
title: '判定',
key: 'passFlag_dictText',
type: JVxeTypes.input,
width: 100,
disabled: true,
},
];

View File

@@ -0,0 +1,70 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #tableTitle>
<a-button
type="primary"
v-auth="'xslmes:mes_xsl_raw_material_inspect_record:exportXls'"
preIcon="ant-design:export-outlined"
@click="onExportXls"
>
导出
</a-button>
</template>
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<MesXslRawMaterialInspectRecordResultModal @register="registerResultModal" @success="reload" />
</div>
</template>
<script lang="ts" name="xslmes-mesXslRawMaterialInspectRecord" setup>
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { useModal } from '/@/components/Modal';
import { columns, searchFormSchema } from './MesXslRawMaterialInspectRecord.data';
import { getExportUrl, list } from './MesXslRawMaterialInspectRecord.api';
import MesXslRawMaterialInspectRecordResultModal from './modules/MesXslRawMaterialInspectRecordResultModal.vue';
const [registerResultModal, { openModal: openResultModal }] = useModal();
const { tableContext, onExportXls } = useListPage({
tableProps: {
title: '原材料送检记录',
api: list,
columns,
canResize: true,
formConfig: { labelWidth: 100, schemas: searchFormSchema, autoSubmitOnEnter: true },
actionColumn: { width: 180, fixed: 'right' },
},
exportConfig: {
name: '原材料送检记录',
url: getExportUrl,
},
});
const [registerTable, { reload }] = tableContext;
function handleEntryResult(record: Recordable) {
openResultModal(true, { record, editable: true });
}
function handleDetail(record: Recordable) {
openResultModal(true, { record, editable: false });
}
function getTableAction(record: Recordable) {
return [
{
label: '录入检验结果',
onClick: handleEntryResult.bind(null, record),
auth: 'xslmes:mes_xsl_raw_material_inspect_record:edit',
ifShow: () => record.inspectStatus === '0',
},
{
label: '查看',
onClick: handleDetail.bind(null, record),
},
];
}
</script>

View File

@@ -0,0 +1,141 @@
<template>
<BasicModal
v-bind="$attrs"
destroyOnClose
:title="title"
width="1100px"
@register="registerModal"
@ok="handleSubmit"
>
<a-descriptions bordered :column="2" size="small">
<a-descriptions-item label="条码">{{ mainRecord.barcode || '-' }}</a-descriptions-item>
<a-descriptions-item label="批次号">{{ mainRecord.batchNo || '-' }}</a-descriptions-item>
<a-descriptions-item label="物料名称">{{ mainRecord.materialName || '-' }}</a-descriptions-item>
<a-descriptions-item label="检验状态">{{ mainRecord.inspectStatus_dictText || '-' }}</a-descriptions-item>
<a-descriptions-item label="送检时间">{{ mainRecord.inspectTime || '-' }}</a-descriptions-item>
<a-descriptions-item label="判定时间">{{ mainRecord.resultTime || '-' }}</a-descriptions-item>
</a-descriptions>
<a-divider orientation="left">检验明细</a-divider>
<JVxeTable
v-if="tableReady"
ref="lineTableRef"
row-number
keep-source
:max-height="400"
:loading="lineLoading"
:columns="tableColumns"
:dataSource="lineDataSource"
:disabled="!editable"
/>
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import type { JVxeTableInstance } from '/@/components/jeecg/JVxeTable/types';
import { lineJVxeColumns } from '../MesXslRawMaterialInspectRecord.data';
import { prepareResultEntry, queryById, queryLineListByRecordId, saveInspectResult } from '../MesXslRawMaterialInspectRecord.api';
import { useMessage } from '/@/hooks/web/useMessage';
const emit = defineEmits(['register', 'success']);
const { createMessage } = useMessage();
const editable = ref(false);
const tableReady = ref(false);
const lineLoading = ref(false);
const lineDataSource = ref<Recordable[]>([]);
const lineTableRef = ref<JVxeTableInstance>();
const recordId = ref('');
const mainRecord = ref<Recordable>({});
const tableColumns = computed(() => {
if (editable.value) {
return lineJVxeColumns;
}
return lineJVxeColumns.map((c) => {
if (c.key === 'inspectValue') {
return { ...c, disabled: true };
}
return c;
});
});
function mapPassFlagText(list: Recordable[]) {
return (list || []).map((row) => {
const passFlag = String(row?.passFlag ?? '');
let passText = '';
if (passFlag === '0') passText = '待检';
else if (passFlag === '1') passText = '合格';
else if (passFlag === '2') passText = '不合格';
return { ...row, passFlag_dictText: passText };
});
}
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
tableReady.value = false;
lineDataSource.value = [];
editable.value = !!data?.editable;
recordId.value = data?.record?.id || '';
setModalProps({
confirmLoading: false,
showCancelBtn: true,
showOkBtn: editable.value,
okText: '保存',
});
if (!recordId.value) {
return;
}
lineLoading.value = true;
try {
const mainRaw = await queryById({ id: recordId.value });
mainRecord.value = (mainRaw as any)?.id != null ? (mainRaw as Recordable) : ((mainRaw as any)?.result ?? {});
if (editable.value) {
const linesRaw = await prepareResultEntry(recordId.value);
const list = Array.isArray(linesRaw) ? linesRaw : ((linesRaw as any)?.result ?? []);
lineDataSource.value = mapPassFlagText(list || []);
} else {
const linesRaw = await queryLineListByRecordId({ id: recordId.value });
const list = Array.isArray(linesRaw) ? linesRaw : ((linesRaw as any)?.result ?? []);
lineDataSource.value = mapPassFlagText(list || []);
}
} finally {
lineLoading.value = false;
tableReady.value = true;
}
});
const title = computed(() => (editable.value ? '录入检验结果' : '送检记录详情'));
async function handleSubmit() {
if (!editable.value) {
closeModal();
return;
}
try {
const lineRef = lineTableRef.value as any;
if (lineRef?.validateTable) {
const err = await lineRef.validateTable();
if (err) {
createMessage.warning('请完善检验值');
return;
}
}
const tableData = (lineRef?.getTableData?.() || []) as Recordable[];
const lineList = tableData.map((item) => ({
id: item.id,
inspectValue: item.inspectValue,
}));
setModalProps({ confirmLoading: true });
await saveInspectResult({
id: recordId.value,
lineList,
});
createMessage.success('保存成功');
closeModal();
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>