1、板材导入优化,一次性查询商品编号、属性组合唯一性在内存中排重;2、新增支持板材名称、材质、颜色、厚度、品牌、纹路在组织内唯一;

This commit is contained in:
gaoqr
2025-07-03 16:17:12 +08:00
parent cac84cb40b
commit b7ee75e9e4
9 changed files with 140 additions and 36 deletions
@@ -124,26 +124,9 @@ public class PlateManageController {
@Operation(summary = "获得导入用户模板")
@PreAuthorize("@ss.hasAnyPermissions('system:plate:export-template','base:plate:export-template')")
public void importTemplate(HttpServletResponse response) throws IOException {
// // 手动创建导出 demo
// List<PlateImportExcelVO> list = Arrays.asList(
// PlateImportExcelVO.builder().goodsId("BD10010001").goodsName("18mm-多层板-暖白").material("多层板").width(String.valueOf(1220)).height(String.valueOf(2440))
// .thickness(String.valueOf(18)).brand("AAA").spec("2440*1220*18").color("暖白").price("120").texture("无").build(),
// PlateImportExcelVO.builder().goodsId("BD10010002").goodsName("18mm-颗粒板-高级灰").material("多层板").width(String.valueOf(1220)).height(String.valueOf(2750))
// .thickness(String.valueOf(18)).brand("鸿达树").spec("2750*1220*18").color("高级灰").price("120").texture("无").build()
// );
// // 输出
// ExcelUtils.write(response, IMPORT_TEMPLATE, "板材列表", PlateImportExcelVO.class, list);
plateService.exportTemplate(response, "excel_plate_add.xlsx");
}
// @GetMapping("/get-import-template")
// @Operation(summary = "获得导入板材模板")
// @Parameter(name = "value", description = "文件类型", required = true, example = "0")
// public void importTemplate(HttpServletResponse response, @RequestParam("value") @NotEmpty(message = "文件路径不能为空") String value) {
// plateService.exportTemplate(response, value);
// }
@PostMapping("/import")
@Operation(summary = "导入板材")
@Parameters({
@@ -152,14 +135,13 @@ public class PlateManageController {
@Parameter(name = "organId", description = "板材所属组织ID")
})
@OperateLog(type = IMPORT)
// @PreAuthorize("@ss.hasPermission('manage:plate:import')")
@PreAuthorize("@ss.hasAnyPermissions('manage:plate:import','base:plate:import')")
public void importExcel(@RequestParam("file") MultipartFile file,
@RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport,
@RequestParam(value = "organId") Long organId,
HttpServletResponse response) throws Exception {
ExcelReadUtil excelReadUtil = new ExcelReadUtil();
PlateExcelListener listener = new PlateExcelListener(updateSupport, plateService);
PlateExcelListener listener = new PlateExcelListener(updateSupport, plateService, organId);
List<PlateImportExcelVO> list = excelReadUtil.read(file, PlateImportExcelVO.class, listener);
// 判断文件是否导入成功
@@ -174,8 +156,6 @@ public class PlateManageController {
plateService.importPlateList(list, updateSupport, organId);// 成功,批量导入
}
}
// plateExcelUtil.clear();
}
@@ -3,6 +3,7 @@ package com.cf.imes.module.executor.controller.admin.manage.plate.vo.plate;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.cf.imes.framework.excel.core.annotations.DictFormat;
import com.cf.imes.framework.excel.core.convert.DictConvert;
import com.cf.imes.module.executor.enums.DictTypeConstants;
@@ -21,19 +22,19 @@ public class PlateRespVO {
private Long id;
@Schema(description = "客户的商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("商品编号")
@ExcelProperty("*商品编号")
private String goodsId;
@Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
@ExcelProperty("商品名称")
@ExcelProperty("*商品名称")
private String goodsName;
@Schema(description = "材质:颗粒板、欧松板、多层板、生态板、禾香板、密度板、实木、铝蜂窝板、铝塑板", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("材质")
@ExcelProperty("*材质")
private String material;
@Schema(description = "颜色", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("颜色")
@ExcelProperty("*颜色")
private String color;
@Schema(description = "纹理", example = "")
@@ -50,7 +51,8 @@ public class PlateRespVO {
private Double height;
@Schema(description = "厚度", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("厚度")
@ExcelProperty("*厚度")
@ColumnWidth(10)
private Double thickness;
@Schema(description = "价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "3380")
@@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.LinkedHashMap;
import java.util.List;
/**
@@ -179,4 +180,11 @@ public interface PlateGoodMapper extends BaseMapperX<PlateGoodDO> {
.eq(PlateGoodDO::getDeleted, 0));
}
/**
* 查询机构下名称、材质、颜色、厚度、品牌、纹路的分组
*
* @param organId
* @return
*/
List<LinkedHashMap<String, Object>> getOrgAttrGroup(@Param("organId") Long organId);
}
@@ -10,8 +10,11 @@ import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
public final class PlateExcelListener<T> extends ExcelListener<PlateImportExcelVO> {
@@ -30,9 +33,24 @@ public final class PlateExcelListener<T> extends ExcelListener<PlateImportExcelV
private PlateManageService plateManageService;
public PlateExcelListener(boolean updateSupport, PlateManageService plateManageService) {
private Set<String> plateGoodsId;
private List<String> orgAttrGroupList;
public PlateExcelListener(boolean updateSupport, PlateManageService plateManageService, Long organId) {
this.updateSupport = updateSupport;
this.plateManageService = plateManageService;
// 查询机构下的所有板材商品编号
plateGoodsId = plateManageService.getOrgPlateGoodsId(organId);
// 查询机构下名称、材质、颜色、厚度、品牌、纹路的分组
List<LinkedHashMap<String, Object>> orgAttrGroup = plateManageService.getOrgAttrGroup(organId);
orgAttrGroupList = orgAttrGroup.stream()
.map(map -> map.values().stream()
.map(String::valueOf) // 确保都转为字符串
.collect(Collectors.joining("-")))
.collect(Collectors.toList());
}
/**
@@ -60,6 +78,8 @@ public final class PlateExcelListener<T> extends ExcelListener<PlateImportExcelV
if (!updateSupport) {
checkGoodsId(data.getGoodsId(),"物料编号",data);
}
// 检查属性组合组织内唯一性
checkAttrGroup(data);
// 字段长度判断
checkLength(data.getGoodsId(),"物料编号",data,32);
checkLength(data.getGoodsName(),"物料名称",data,64);
@@ -75,14 +95,31 @@ public final class PlateExcelListener<T> extends ExcelListener<PlateImportExcelV
datas.add(data);
}
// 错误判断
// goodsId存在判断
/**
* 检查属性组合(名称、材质、颜色、厚度、品牌、纹路)是否存在
*
* @param data
*/
private void checkAttrGroup(PlateImportExcelVO data) {
String checkKey = data.getGoodsName() + "-" + data.getMaterial() + "-" + data.getColor() + "-" + Double.valueOf(data.getThickness()) + "-" + (StringUtils.isNotEmpty(data.getBrand()) ? data.getBrand() : "") + "-" + data.getTexture();
if (orgAttrGroupList.contains(checkKey)) {
this.flag = false;
data.setResult(data.getResult() + "," + "名称、材质、颜色、厚度、品牌、纹路的组合已存在");
}
}
/**
* 检查商品编号是否存在
* @param valueCheck
* @param head
* @param data
*/
private void checkGoodsId(String valueCheck, String head, PlateImportExcelVO data) {
if (valueCheck != null && !valueCheck.equals("")) {
String value = valueCheck.trim();
if (plateManageService.getPlateGoods(value) != null) {
if (plateGoodsId.contains(value)) {
this.flag = false;
data.setResult(data.getResult() + "," + head + "信息重复");
data.setResult(data.getResult() + "," + head + "已存在");
}
}
}
@@ -11,7 +11,9 @@ import org.springframework.boot.system.ApplicationHome;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
/**
* 板材信息表 plate_{N} Service 接口
@@ -96,5 +98,26 @@ public interface PlateManageService {
}
/**
* 查询机构下所有板材信息
*
* @return
*/
List<PlateGoodDO> getPlateAll();
/**
* 查询机构下所有商品编号
*
* @param organId
* @return
*/
Set<String> getOrgPlateGoodsId(Long organId);
/**
* 查询机构下名称、材质、颜色、厚度、品牌、纹路的分组
*
* @param organId
* @return
*/
List<LinkedHashMap<String, Object>> getOrgAttrGroup(Long organId);
}
@@ -7,6 +7,7 @@ import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.organ.core.aop.OrganIgnore;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.module.executor.controller.admin.manage.plate.vo.plate.PlateImportExcelVO;
@@ -28,9 +29,11 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -43,6 +46,7 @@ import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.ge
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.PLATE_IMPORT_INTERRUPT_ERROR;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.PLATE_IMPORT_QUERY_INTERRUPT_ERROR;
import static com.cf.imes.module.executor.framework.executor.config.ExecutorThreadPoolConfiguration.EXECUTOR_IMPOT_THREAD_POOL_TASK_EXECUTOR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PLATE_ATTR_GROUP_EXISTS;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PLATE_GOODS_ID_NOT_SAME;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.REMAIN_PLATE_NOT_EXISTS;
@@ -85,9 +89,12 @@ public class PlateManageServiceImpl implements PlateManageService {
public Long createPlate(PlateSaveReqVO createReqVO) {
PlateGoodDO plate = BeanUtils.toBean(createReqVO, PlateGoodDO.class);
Long organId = getOrganId(BASE_PLATE_CREATE_PERMISSION, getLoginUser().getId(), plate.getOrganId());
// 判断板材是否存在
validateGoodExists(plate.getGoodsId(),
getOrganId(BASE_PLATE_CREATE_PERMISSION, getLoginUser().getId(), plate.getOrganId()));
validateGoodExists(plate.getGoodsId(), organId);
// 校验板材名称、材质、颜色、厚度、品牌、纹路在组织内唯一
validateGoodAttr(plate, organId);
plateGoodMapper.insert(plate);// 组织id未传输
// 返回
@@ -110,9 +117,35 @@ public class PlateManageServiceImpl implements PlateManageService {
if (plateGoodMapper.isByGoodIDAndId(updateReqVO.getGoodsId(), organId, Long.valueOf(updateReqVO.getId()))) {
throw exception(PLATE_GOODS_ID_NOT_SAME);
}
// 校验板材名称、材质、颜色、厚度、品牌、纹路在组织内唯一
validateGoodAttr(updateObj, organId);
plateGoodMapper.updateById(updateObj);
}
/**
* 校验板材名称、材质、颜色、厚度、品牌、纹路在组织内唯一
*
* @param plate
*/
private void validateGoodAttr(PlateGoodDO plate, Long organId) {
if (ObjectUtil.isNull(plate.getTexture())) {
plate.setTexture(false);
}
Long count = plateGoodMapper.selectCount(new LambdaQueryWrapperX<PlateGoodDO>()
.eq(PlateGoodDO::getGoodsName, plate.getGoodsName())
.eq(PlateGoodDO::getOrganId, organId)
.eq(PlateGoodDO::getMaterial, plate.getMaterial())
.eq(PlateGoodDO::getColor, plate.getColor())
.eq(PlateGoodDO::getThickness, plate.getThickness())
.eqIfPresent(PlateGoodDO::getBrand, plate.getBrand())
.neIfPresent(PlateGoodDO::getId, plate.getId())
.eq(PlateGoodDO::getTexture, plate.getTexture()));
if (count > 0) {
throw exception(PLATE_ATTR_GROUP_EXISTS);
}
}
@Override
@OrganIgnore
@Transactional(rollbackFor = Exception.class)
@@ -367,6 +400,22 @@ public class PlateManageServiceImpl implements PlateManageService {
return plateGoodMapper.getAllByOrganId(OrganContextHolder.getOrganId());
}
@Override
@OrganIgnore
public Set<String> getOrgPlateGoodsId(Long organId) {
return plateGoodMapper.selectList(new LambdaQueryWrapper<PlateGoodDO>()
.eq(PlateGoodDO::getOrganId, getOrganId(BASE_PLATE_IMPORT_PERMISSION, getLoginUser().getId(), organId))
.eq(PlateGoodDO::getDeleted, false)
.select(PlateGoodDO::getGoodsId))
.stream().map(PlateGoodDO::getGoodsId).collect(Collectors.toSet());
}
@Override
@OrganIgnore
public List<LinkedHashMap<String, Object>> getOrgAttrGroup(Long organId) {
return plateGoodMapper.getOrgAttrGroup(organId);
}
private void validateOrganExists(Long organId) {
CommonResult<Boolean> index = organApi.validOrgan(organId);
if (!index.isSuccess()) {
@@ -27,4 +27,11 @@
where organ_id = #{organId} and id = #{id} and deleted = 0
</select>
<select id="getOrgAttrGroup" resultType="java.util.LinkedHashMap">
select goods_name, material, color, thickness, brand, texture
from plate
where organ_id = #{organId}
and deleted = false
group by goods_name, material, color, thickness, brand, texture;
</select>
</mapper>
@@ -268,9 +268,7 @@ public class ErrorCodeConstants {
public static final ErrorCode PLATE_NOT_EXISTS = new ErrorCode(1_002_033_008, "板材标识代号禁止空");
public static final ErrorCode PLATE_GOODS_ID_NOT_SAME = new ErrorCode(1_002_033_009, "板材商品编号存在,请重新命名商品编号");
public static final ErrorCode PLATE_IS_SOURCE = new ErrorCode(1_002_033_010, "小板:{} 为源小板,无法删除");
public static final ErrorCode PLAN_GOODS_IS_FILTER_DATA_ERROR = new ErrorCode(1_002_033_011, "当前排单为非混单,无法添加颜色的筛选条件");
public static final ErrorCode PLAN_STATUS_ERROR = new ErrorCode(1_002_033_012, "当前排单未投产,无法进行开料");
public static final ErrorCode PLATE_ATTR_GROUP_EXISTS = new ErrorCode(1_002_033_011, "当前名称、材质、颜色、厚度、品牌、纹路的组合已存在,请检查后提交");
//=========== 工序信息 1-002-034-000 ============