fix:物料大类的实例配单独的编号规则;

This commit is contained in:
shusir
2026-03-17 16:25:33 +08:00
parent 1f4f44af00
commit 7f2b6ea261
16 changed files with 152 additions and 40 deletions

View File

@@ -215,6 +215,7 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler
// 添加到上下文中,避免重复计算
loginUser.setContext(QMS_PERMISSION_CONTEXT_KEY, qmsDataPermission);
}
Long ctxDeptId = DeptContextHolder.getDeptId();
// 计算有效的部门与自查标记:当存在上下文部门且未被忽略时,强制仅使用该部门,以避免默认全量或空权限分支
Set<Long> effectiveDeptIds = qmsDataPermission.getDeptIds();
@@ -234,9 +235,10 @@ public class QMSMultiDataPermissionHandler implements MultiDataPermissionHandler
}
// 情况二:仅在有效部门集合为空且不可查看自己时,才认为无权限;若上下文提供部门,则跳过该兜底
if (CollUtil.isEmpty(effectiveDeptIds) && Boolean.FALSE.equals(effectiveSelf)) {
return new EqualsTo(null, null); // WHERE null = null可以保证返回的数据为空
}
// TODO 这个逻辑暂时先注释,好像是存在用户角色时,不会设置部门
// if (CollUtil.isEmpty(effectiveDeptIds) && Boolean.FALSE.equals(effectiveSelf)) {
// return new EqualsTo(null, null); // WHERE null = null可以保证返回的数据为空
// }
// 情况三,拼接 Dept 和 Company User 的条件,最后组合
Expression deptExpression = buildDeptExpression(tableName, deptIdCol, tableAlias, effectiveDeptIds);

View File

@@ -153,7 +153,7 @@ public class MaterialBatchController implements BusinessControllerMarker {
MaterialBatchImportExcelVO.builder()
.productName("无水硼砂")
.productCode("W11174909")
.productModelNo("95%")
.productSpecification("95%")
.supplier("供应商 1")
.manufacturerDate(LocalDate.parse("2026-03-15"))
.dueDate(LocalDate.parse("2026-08-11"))
@@ -164,7 +164,7 @@ public class MaterialBatchController implements BusinessControllerMarker {
MaterialBatchImportExcelVO.builder()
.productName("氧化钙")
.productCode("W10102372")
.productModelNo("AR500g/瓶")
.productSpecification("AR")
.supplier("供应商 2")
.manufacturerDate(LocalDate.parse("2026-04-16"))
.dueDate(LocalDate.parse("2026-09-18"))

View File

@@ -1,12 +1,18 @@
package com.zt.plat.module.qms.resource.material.controller.admin;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
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.MaterialInfomationSaveReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.export.MaterialLedgerExportVO;
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.MaterialInfomationDO;
import com.zt.plat.module.qms.resource.material.service.MaterialInfomationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@@ -35,6 +41,7 @@ import com.zt.plat.framework.apilog.core.annotation.ApiAccessLog;
import static com.zt.plat.framework.apilog.core.enums.OperateTypeEnum.*;
@Slf4j
@Tag(name = "管理后台 - 物料实例")
@RestController
@RequestMapping("/qms/resource/material-infomation")
@@ -126,18 +133,33 @@ public class MaterialInfomationController implements BusinessControllerMarker {
}
@GetMapping("/export-ledger")
@Operation(summary = "导出危化品台账")
@Operation(summary = "导出台账")
public void exportHazardousLedger(@Valid MaterialInfomationPageReqVO pageReqVO, HttpServletResponse response) throws IOException {
// ArrayList<MaterialHazardousLedgerExportVO> exportVOS = getLedgerExportVOS();
// 暂时只获取危化品台账
pageReqVO.setHazardous(1);
PageResult<MaterialInfomationLedgerRespVO> pageResult = materialInfomationService.getMaterialInventoryLedgerPage(pageReqVO);
// // 3. 导出 Excel
// ComplexExcelUtils.writeHazardousLedger(
// response, "危险化学品管理台账.xls", "危险化学品管理台账", exportVOS
//
// );
// 导出 Excel
List<MaterialInfomationLedgerRespVO> list = pageResult.getList();
if (CollUtil.isEmpty(list)) {
ExcelUtils.write(response, "物料危化品库存台账.xls", "危化品库存台账", MaterialLedgerExportVO.class,
BeanUtils.toBean(list, MaterialLedgerExportVO.class));
return;
}
List<MaterialLedgerExportVO> exportVOS = list.stream().map(respVO -> {
MaterialLedgerExportVO exportVO = BeanUtils.toBean(respVO, MaterialLedgerExportVO.class);
JSONObject productCustomConfig = respVO.getProductCustomConfig();
if (productCustomConfig == null) return exportVO;
MaterialLedgerExportVO extraProps = productCustomConfig.get("extraProps", MaterialLedgerExportVO.class);
if (extraProps == null) return exportVO;
BeanUtil.copyProperties(extraProps, exportVO, CopyOptions.create().setIgnoreNullValue(true));
return exportVO;
}).toList();
ExcelUtils.write(response, "物料危化品库存台账.xls", "危化品库存台账",
MaterialLedgerExportVO.class,
exportVOS);
}
}

View File

@@ -1,12 +1,10 @@
package com.zt.plat.module.qms.resource.material.controller.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
import com.zt.plat.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;

View File

@@ -42,6 +42,10 @@ public class MaterialBatchRespVO {
@ExcelProperty("物料大类编码")
private String productCode;
@Schema(description = "物料大类规格")
@ExcelProperty("物料大类规格")
private String productSpecification;
@Schema(description = "物料大类型号")
@ExcelProperty("物料大类型号")
private String productModelNo;
@@ -94,6 +98,10 @@ public class MaterialBatchRespVO {
@ExcelProperty("供应商id")
private Long supplierId;
@Schema(description = "供应商")
@ExcelProperty("供应商")
private String supplierName;
@Schema(description = "生产日期")
@ExcelProperty("生产日期")
private LocalDateTime manufacturerDate;

View File

@@ -26,8 +26,8 @@ public class MaterialBatchImportExcelVO {
@ExcelProperty("物料编码")
private String productCode;
@ExcelProperty("物料型号")
private String productModelNo;
@ExcelProperty("物料规格")
private String productSpecification;
@ExcelProperty("供应商")
private String supplier;

View File

@@ -134,6 +134,16 @@ public class MaterialInfomationDO extends BusinessBaseDO {
@TableField("MNGR_USER_NAME")
private String managerUserName;
/**
* 所属部门id
*/
@TableField("BLG_DEPT_ID")
private Long belongDepartmentId;
/**
* 所属部门
*/
@TableField("BLG_DEPT_NAME")
private String belongDepartmentName;
/**
* 开封状态,0-未开封1-已开封
*/
@TableField("OPN_STS")

View File

@@ -11,6 +11,7 @@ import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.qms.core.aspect.annotation.QmsPermission;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import com.zt.plat.module.qms.office.supplier.dal.dataobject.SupplierDO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialBatchPageReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialBatchRespVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialBatchDO;
@@ -48,7 +49,7 @@ public interface MaterialBatchMapper extends BaseMapperX<MaterialBatchDO> {
.orderByDesc(MaterialBatchDO::getId));
}
@QmsPermission(moduleDataRoleCodes = "ytjyAdmin", deptIdColumn = "ASN_DEPT_ID")
@QmsPermission(deptIdColumn = "ASN_DEPT_ID")
default PageResult<MaterialBatchRespVO> selectPageWithPdtInfo(MaterialBatchPageReqVO reqVO, List<Long> pdtIds) {
MPJLambdaWrapper<MaterialBatchDO> wrapper = new MPJLambdaWrapperX<MaterialBatchDO>()
@@ -56,14 +57,17 @@ public interface MaterialBatchMapper extends BaseMapperX<MaterialBatchDO> {
.selectAs(MaterialProductDO::getName, MaterialBatchRespVO::getProductName)
.selectAs(MaterialProductDO::getCode, MaterialBatchRespVO::getProductCode)
.selectAs(MaterialProductDO::getStandardCapacity, MaterialBatchRespVO::getStandardCapacity)
.selectAs(MaterialProductDO::getSpecification, MaterialBatchRespVO::getProductSpecification)
.selectAs(MaterialProductDO::getModelNo, MaterialBatchRespVO::getProductModelNo)
// 标签模板,用于入库
.selectAs(MaterialProductDO::getLabelTemplateKey, MaterialBatchRespVO::getLabelTemplateKey)
// 生产日期和到期日期,用于验收和入库
.selectAs("batch.MFR_DT", MaterialBatchDO::getManufacturerDate)
.selectAs("batch.DUE_DT", MaterialBatchDO::getDueDate)
.selectAs(SupplierDO::getName, MaterialBatchRespVO::getSupplierName)
.leftJoin(MaterialProductDO.class, MaterialProductDO::getId, MaterialBatchDO::getProductId)
.leftJoin(MaterialBatchDO.class, "batch", MaterialBatchDO::getId, MaterialBatchDO::getParentId)
.leftJoin(SupplierDO.class, SupplierDO::getId, MaterialBatchDO::getSupplierId)
// 只要批次
.eq(MaterialBatchGongType.batch.name().equals(reqVO.getDataType()), MaterialBatchDO::getParentId, 0)
// 只要工段

View File

@@ -7,6 +7,7 @@ import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigWarehouseLocationDO;
import com.zt.plat.module.qms.core.aspect.annotation.QmsPermission;
import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceConfigBusinessRuleDO;
import com.zt.plat.module.qms.resource.device.dal.dataobject.DeviceProductDO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInfomationPageReqVO;
@@ -55,6 +56,7 @@ public interface MaterialInfomationMapper extends BaseMapperX<MaterialInfomation
.orderByDesc(MaterialInfomationDO::getId));
}
@QmsPermission(deptIdColumn = "BLG_DEPT_ID")
default PageResult<MaterialInfomationRespVO> selectPageWithPdtInfo(MaterialInfomationPageReqVO reqVO) {
MPJLambdaWrapper<MaterialInfomationDO> wrapper = new MPJLambdaWrapperX<MaterialInfomationDO>()
.select(MaterialInfomationDO::getId,
@@ -233,7 +235,7 @@ public interface MaterialInfomationMapper extends BaseMapperX<MaterialInfomation
default PageResult<MaterialInfomationLedgerRespVO> selectInventoryLedgerPage(MaterialInfomationPageReqVO reqVO) {
MPJLambdaWrapper<MaterialInfomationDO> wrapper = new MPJLambdaWrapperX<MaterialInfomationDO>()
.select(MaterialInfomationDO::getProductId)
.selectAs(MaterialInfomationDO::getDeptId, MaterialInfomationLedgerRespVO::getDepartmentId)
.selectAs(MaterialInfomationDO::getBelongDepartmentId, MaterialInfomationLedgerRespVO::getDepartmentId)
.select(MaterialInfomationDO::getLocationId)
.selectCount(MaterialInfomationDO::getId, MaterialInfomationLedgerRespVO::getDepartmentInventoryQuantity)
.innerJoin(MaterialProductDO.class, MaterialProductDO::getId, MaterialInfomationDO::getProductId)
@@ -241,7 +243,7 @@ public interface MaterialInfomationMapper extends BaseMapperX<MaterialInfomation
.eq(MaterialInfomationDO::getUsageStatus, 0)
.likeIfExists(MaterialProductDO::getName, reqVO.getName())
.groupBy(MaterialInfomationDO::getProductId,
MaterialInfomationDO::getDeptId,
MaterialInfomationDO::getBelongDepartmentId,
MaterialInfomationDO::getLocationId);
return selectJoinPage(reqVO, MaterialInfomationLedgerRespVO.class, wrapper);

View File

@@ -395,7 +395,7 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
} else {
pageResult = materialBatchMapper.selectPageWithPdtInfo(pageReqVO, List.of());
}
log.info("pageResult:{}", pageResult.getList());
// 给批次设置顶级分类的json配置
if (StrUtil.isEmpty(pageReqVO.getDataType()) || MaterialBatchGongType.batch.name().equals(pageReqVO.getDataType())) {
List<MaterialBatchRespVO> batches = pageResult.getList();
@@ -531,11 +531,12 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
// 检验
for (MaterialBatchImportExcelVO batch : importList) {
if (StrUtil.isEmpty(batch.getProductCode())) throw new ServiceException(1_032_160_000, "物料编码不能为空");
if (batch.getInboundQuantity() == null || batch.getInboundQuantity().compareTo(BigDecimal.ZERO) < 0)
throw new ServiceException(1_032_160_000, "批次数量不能小于0");
if (StrUtil.isEmpty(batch.getProductSpecification())) throw new ServiceException(1_032_160_000, "物料规格不能为空");
if (batch.getInboundQuantity() == null || batch.getInboundQuantity().compareTo(BigDecimal.ZERO) <= 0)
throw new ServiceException(1_032_160_000, "批次数量需要大于0");
}
// 获取大类id 每个物料都得校验是否存在
Set<String> pdtCodes = importList.stream().map(MaterialBatchImportExcelVO::getProductCode).collect(Collectors.toSet());
/*Set<String> pdtCodes = importList.stream().map(MaterialBatchImportExcelVO::getProductCode).collect(Collectors.toSet());
List<MaterialProductDO> products = materialProductService.getProductListByPdtCodes(new ArrayList<>(pdtCodes));
if (CollUtil.isEmpty(products)) throw new ServiceException(1_032_160_000, "未找到对应的物料");
Map<String, MaterialProductDO> productDOMapByCode = products.stream().collect(Collectors.toMap(MaterialProductDO::getCode, Function.identity()));
@@ -549,6 +550,30 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
if (CollUtil.isNotEmpty(notFoundCodes)) {
throw new ServiceException(1_032_160_000, "未找到以下物料:" + String.join(", ", notFoundCodes));
}
}*/
// 获取物料编码和规格,使用编码 + 规格匹配物料
Set<String> pdtCodes = importList.stream().map(MaterialBatchImportExcelVO::getProductCode).collect(Collectors.toSet());
Set<String> specifications = importList.stream().map(MaterialBatchImportExcelVO::getProductSpecification).collect(Collectors.toSet());
List<MaterialProductDO> products = materialProductService.getProductListByCodeAndSpec(new ArrayList<>(pdtCodes), new ArrayList<>(specifications));
if (CollUtil.isEmpty(products)) throw new ServiceException(1_032_160_000, "未找到对应的物料");
// 构建编码 + 规格的组合键用于校验
Map<String, MaterialProductDO> productDOMapByKey = products.stream().collect(Collectors.toMap(
p -> p.getCode() + "_" + p.getSpecification(),
Function.identity(),
(v1, v2) -> v1
));
// 校验是否所有导入的物料都能找到
List<String> notFoundMaterials = new ArrayList<>();
for (MaterialBatchImportExcelVO importItem : importList) {
String key = importItem.getProductCode() + "_" + importItem.getProductSpecification();
if (!productDOMapByKey.containsKey(key)) {
notFoundMaterials.add(String.format("物料【%s】+【%s】", importItem.getProductCode(), importItem.getProductSpecification()));
}
}
if (CollUtil.isNotEmpty(notFoundMaterials)) {
throw new ServiceException(1_032_160_000, "未找到以下物料:" + String.join(", ", notFoundMaterials));
}
// 获取供应商
Set<String> supplierNames = importList.stream().map(MaterialBatchImportExcelVO::getSupplier).filter(Objects::nonNull).collect(Collectors.toSet());
@@ -573,7 +598,9 @@ public class MaterialBatchServiceImpl implements MaterialBatchService {
// 保存批次
Map<String, SupplierDO> finalSupplierDOMapByName = supplierDOMapByName;
List<MaterialBatchDO> batchDOS = importList.stream().map(importBat -> {
MaterialProductDO productDO = productDOMapByCode.get(importBat.getProductCode());
String key = importBat.getProductCode() + "_" + importBat.getProductSpecification();
MaterialProductDO productDO = productDOMapByKey.get(key);
// MaterialProductDO productDO = productDOMapByCode.get(importBat.getProductCode());
LocalDate manufacturerDate = importBat.getManufacturerDate();
MaterialBatchDO batchDO = new MaterialBatchDO()
.setParentId(0L)

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