fix:物料危化品台账

This commit is contained in:
shusir
2026-03-13 18:11:43 +08:00
parent 9d43ce6a62
commit 2b79f10072
15 changed files with 866 additions and 11 deletions

View File

@@ -71,4 +71,12 @@ public interface ConfigWarehouseLocationService {
PageResult<ConfigWarehouseLocationRespVO> getConfigWarehouseLocationPage(ConfigWarehouseLocationPageReqVO pageReqVO);
List<ConfigWarehouseLocationDO> selectListWithPermission(ConfigWarehouseLocationPageReqVO pageReqVO);
/**
* 获得存放位置列表
*
* @param ids id集合
* @return 存放位置列表
*/
List<ConfigWarehouseLocationDO> getListByIds(List<Long> ids);
}

View File

@@ -178,4 +178,10 @@ public class ConfigWarehouseLocationServiceImpl implements ConfigWarehouseLocati
public List<ConfigWarehouseLocationDO> selectListWithPermission(ConfigWarehouseLocationPageReqVO pageReqVO) {
return configWarehouseLocationMapper.selectListWithPermission(pageReqVO);
}
@Override
public List<ConfigWarehouseLocationDO> getListByIds(List<Long> ids) {
return configWarehouseLocationMapper.selectByIds(ids);
}
}

View File

@@ -15,19 +15,23 @@ import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryO
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryOutboundRespVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryOutboundSaveReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.export.MaterialConsumeStatisticsExportVO;
import com.zt.plat.module.qms.resource.material.controller.vo.export.MaterialHazardousLedgerExportVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialInventoryOutboundDO;
import com.zt.plat.module.qms.resource.material.service.MaterialInventoryOutboundService;
import com.zt.plat.module.qms.resource.material.utils.ComplexExcelUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.jspecify.annotations.NonNull;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static com.zt.plat.framework.apilog.core.enums.OperateTypeEnum.EXPORT;

View File

@@ -0,0 +1,53 @@
package com.zt.plat.module.qms.resource.material.controller.vo.export;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 物料危化品台账导出VO")
@Data
//@ExcelIgnoreUnannotated
public class MaterialHazardousLedgerExportVO {
// 基础信息
private Integer serialNo; // 序号
private String company; // 单位
private String name; // 名称
private String substance; // 物质 json
private String hazardFeature; // 危险特性 json
private String englishName; // 英文名 json
private String alias; // 别名 json
private String hazardCategory; // 危险类别 json
private String isToxic; // 是否剧毒 json
private String casNo; // CAS 号 json
private String unNo; // UN 号 json
private String hazardCode; // 危规号 json
// 储存情况 - 合计
private String totalQuantity; // 储存量合计 (瓶)
// 化学分析室
private String chemStoreLocation; // 存放地点
private String chemQuantity; // 储存量 (瓶)
private String chemSpec; // 规格
private String chemUseLocation; // 使用地点 json
private String chemUse; // 用途 json
// 综合分析室
private String compStoreLocation; // 存放地点
private String compQuantity; // 储存量 (瓶)
private String compSpec; // 规格
private String compUseLocation; // 使用地点
private String compUse; // 用途
// 试金分析室
private String trialStoreLocation; // 存放地点
private String trialQuantity; // 储存量 (瓶)
private String trialSpec; // 规格
private String trialUseLocation; // 使用地点
private String trialUse; // 用途
// 其他
private String isExplosive; // 易制爆
private String isPoisonous; // 易制毒
private String remark; // 备注
}

View File

@@ -12,10 +12,10 @@ import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceProductDO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInfomationPageReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInfomationRespVO;
import com.zt.plat.module.qms.resource.material.controller.vo.query.MaterialInfomationQueryVO;
import com.zt.plat.module.qms.resource.material.controller.vo.resp.MaterialInfomationLedgerRespVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.*;
import org.apache.ibatis.annotations.Mapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -229,4 +229,17 @@ public interface MaterialInfomationMapper extends BaseMapperX<MaterialInfomation
return selectJoinList(MaterialInfoWithBizConfigVO.class, wrapper);
}
default PageResult<MaterialInfomationLedgerRespVO> selectInventoryLedgerPage(MaterialInfomationPageReqVO pageReqVO) {
MPJLambdaWrapper<MaterialInfomationDO> wrapper = new MPJLambdaWrapperX<MaterialInfomationDO>()
.select(MaterialInfomationDO::getProductId)
.selectAs(MaterialInfomationDO::getDeptId, MaterialInfomationLedgerRespVO::getAssignDepartmentId)
.select(MaterialInfomationDO::getLocationId)
.selectCount(MaterialInfomationDO::getId, MaterialInfomationLedgerRespVO::getAssignDepartmentInventoryQuantity)
.groupBy(MaterialInfomationDO::getProductId,
MaterialInfomationDO::getDeptId,
MaterialInfomationDO::getLocationId);
return selectJoinPage(pageReqVO, MaterialInfomationLedgerRespVO.class, wrapper);
}
}

View File

@@ -0,0 +1,94 @@
package com.zt.plat.module.qms.resource.material.handler.excel;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Row;
public class MaterialHazardousLedgerHeadHandler implements RowWriteHandler {
@Override
public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
/*if (!isHead || relativeRowIndex != 0) {
return;
}
var sheet = writeSheetHolder.getSheet();
// 第一行:大标题
var titleRow = sheet.getRow(0);
var titleCell = titleRow.createCell(0);
titleCell.setCellValue("云铜检测危化品管理台账");
// 第二行:基础信息和储存情况
var row2 = sheet.getRow(1);
var baseInfoCell = row2.createCell(0);
baseInfoCell.setCellValue("基础信息");
var storageInfoCell = row2.createCell(13);
storageInfoCell.setCellValue("储存情况");
// 第三行:详细表头
var row3 = sheet.getRow(2);
String[] headers = {"序号", "单位", "名称", "物质", "危险特性", "英文名", "别名",
"危险类别", "是否剧毒", "CAS 号", "UN 号", "危规号",
"储存量合计", "化学分析室", "", "", "", "",
"综合分析室", "", "", "", "",
"试金分析室", "", "", "", "",
"易制爆", "易制毒", "备注"};
for (int i = 0; i < headers.length; i++) {
var cell = row3.createCell(i);
cell.setCellValue(headers[i]);
}*/
// 只在写入表头的第 0 行时执行
if (!isHead || relativeRowIndex != 0) {
return;
}
var sheet = writeSheetHolder.getSheet();
// 1. 处理第 0 行(大标题)
var titleRow = sheet.getRow(0);
if (titleRow == null) {
titleRow = sheet.createRow(0);
}
var titleCell = titleRow.createCell(0);
titleCell.setCellValue("云铜检测危化品管理台账");
// 2. 处理第 1 行(基础信息、储存情况、易制爆、易制毒、备注)
var row2 = sheet.getRow(1);
if (row2 == null) {
row2 = sheet.createRow(1);
}
// 基础信息 (A列)
row2.createCell(0).setCellValue("基础信息");
// 储存情况 (N列即索引13)
row2.createCell(13).setCellValue("储存情况");
// 易制爆 (AC列索引28)
row2.createCell(28).setCellValue("易制爆");
// 易制毒 (AD列索引29)
row2.createCell(29).setCellValue("易制毒");
// 备注 (AE列索引30)
row2.createCell(30).setCellValue("备注");
// 3. 处理第 2 行(详细列头)
var row3 = sheet.getRow(2);
if (row3 == null) {
row3 = sheet.createRow(2);
}
String[] headers = {
"序号", "单位", "名称", "物质", "危险特性", "英文名", "别名",
"危险类别", "是否剧毒", "CAS 号", "UN 号", "危规号",
"储存量合计", "化学分析室", "", "", "", "",
"综合分析室", "", "", "", "",
"试金分析室", "", "", "", "",
"", "", "" // 易制爆、易制毒、备注在第二行已设置,这里留空
};
for (int i = 0; i < headers.length; i++) {
var cell = row3.createCell(i);
cell.setCellValue(headers[i]);
}
}
}

View File

@@ -0,0 +1,41 @@
package com.zt.plat.module.qms.resource.material.handler.excel;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.util.CellRangeAddress;
public class MaterialHazardousLedgerStyleHandler implements SheetWriteHandler {
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
var sheet = writeSheetHolder.getSheet();
// 合并大标题(第一行 A:AE如果备注列需要可扩展到 AE
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 30));
// 基础信息:只合并第二行 A2:M2
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 12));
// 储存情况:只合并第二行 N2:AB2避开 AC、AD、AE
sheet.addMergedRegion(new CellRangeAddress(1, 1, 13, 27));
// 化学分析室:合并第三行 N3:R3
sheet.addMergedRegion(new CellRangeAddress(2, 2, 13, 17));
// 综合分析室:合并第三行 S3:W3
sheet.addMergedRegion(new CellRangeAddress(2, 2, 18, 22));
// 试金分析室:合并第三行 X3:AB3
sheet.addMergedRegion(new CellRangeAddress(2, 2, 23, 27));
// 易制爆:合并第二行到第三行的 AC 列 (AC2:AC3)
sheet.addMergedRegion(new CellRangeAddress(1, 2, 28, 28));
// 易制毒:合并第二行到第三行的 AD 列 (AD2:AD3)
sheet.addMergedRegion(new CellRangeAddress(1, 2, 29, 29));
// 备注:合并第二行到第三行的 AE 列 (AE2:AE3)
sheet.addMergedRegion(new CellRangeAddress(1, 2, 30, 30));
}
}

View File

@@ -44,6 +44,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@@ -527,7 +528,6 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
if (CollUtil.isEmpty(importList)) throw new ServiceException(1_032_160_000, "导入数据不能为空");
log.info("导入数据:{}", importList);
List<String> successBatchNos = new ArrayList<>();
Map<String, String> failureBatches = new LinkedHashMap<>();
// 检验
for (MaterialBatchImportExcelVO batch : importList) {
if (StrUtil.isEmpty(batch.getProductCode())) throw new ServiceException(1_032_160_000, "物料编码不能为空");
@@ -552,10 +552,12 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
}
// 获取供应商
Set<String> supplierNames = importList.stream().map(MaterialBatchImportExcelVO::getSupplier).filter(Objects::nonNull).collect(Collectors.toSet());
List<SupplierDO> suppliers;
Map<String, SupplierDO> supplierDOMapByName = Map.of();
if (CollUtil.isNotEmpty(supplierNames)) {
List<SupplierDO> suppliers = supplierService.getSuppliersByNames(new ArrayList<>(supplierNames));
suppliers = supplierService.getSuppliersByNames(new ArrayList<>(supplierNames));
if (CollUtil.isEmpty(suppliers)) throw new ServiceException(1_032_160_000, "未找到对应的供应商");
Map<String, SupplierDO> supplierDOMapByName = suppliers.stream().collect(Collectors.toMap(SupplierDO::getName, Function.identity()));
supplierDOMapByName = suppliers.stream().collect(Collectors.toMap(SupplierDO::getName, Function.identity()));
if (supplierNames.size() != suppliers.size()) {
List<String> notFoundNames = new ArrayList<>();
for (String supplierName : supplierNames) {
@@ -568,11 +570,39 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
}
}
}
// 保存批次
Map<String, SupplierDO> finalSupplierDOMapByName = supplierDOMapByName;
List<MaterialBatchDO> batchDOS = importList.stream().map(importBat -> {
MaterialProductDO productDO = productDOMapByCode.get(importBat.getProductCode());
LocalDate manufacturerDate = importBat.getManufacturerDate();
MaterialBatchDO batchDO = new MaterialBatchDO()
.setParentId(0L)
.setProductId(productDO.getId())
.setBatchNo(sequenceUtil.genCode(MaterialConstants.SEQUENCE_BATCH_KEY))
.setInboundQuantity(importBat.getInboundQuantity())
.setRemaineQuantity(importBat.getInboundQuantity())
.setAcceptanceStatus(MaterialAcceptStatus.not_accepted.name())
.setSubmitStatus(0)
.setManufacturerDate(manufacturerDate)
.setLocation(importBat.getLocation())
.setRemark(importBat.getRemark());
SupplierDO supplierDO = finalSupplierDOMapByName.get(importBat.getSupplier());
batchDO.setSupplierId(supplierDO == null ? null : supplierDO.getId());
// 处理到期日期
LocalDate importDueDate = importBat.getDueDate();
Integer due = productDO.getDue();
if (importDueDate != null) {
batchDO.setDueDate(importDueDate);
} else if (manufacturerDate != null && due != null){
batchDO.setDueDate(manufacturerDate.plusDays(due));
}
successBatchNos.add(batchDO.getBatchNo());
return batchDO;
}).toList();
materialBatchMapper.insertBatch(batchDOS);
return new MaterialBatchImportRespVO()
.setSuccessBatchNos(successBatchNos)
.setFailureBatches(failureBatches)
.setSuccessCount(successBatchNos.size())
.setFailureCount(failureBatches.size());
.setSuccessCount(successBatchNos.size());
}

Some files were not shown because too many files have changed in this diff Show More