feat(material-category): 实现物料分类同步及ltree类型支持

- 新增 LtreeTypeHandler,支持PostgreSQL ltree类型与Java String映射
- 在QmsQcMaterialCategory实体中增加parentTree字段,使用LtreeTypeHandler处理
- 添加MaterialCategoryVO和MaterialCategoryQO数据传输对象
- 实现MaterialCategorySyncProcessor,从主物料同步物料分类到QMS
- 同步过程中支持新数据批量插入及已存在数据的更新
- 实现物料分类树形结构的扁平化处理以便同步操作
This commit is contained in:
曹鹏飞 2026-04-14 16:25:05 +08:00
parent 0aaaf451e8
commit 2a7b4df62c
5 changed files with 147 additions and 2 deletions

View File

@ -7,6 +7,8 @@ import java.util.List;
@Data
public class MaterialCategoryVO {
private Long rowId;
/**
* 分类编码
*/
@ -17,5 +19,12 @@ public class MaterialCategoryVO {
*/
private String categoryName;
/**
* 父分类id
*/
private Long parentCategoryRowId;
private String parentTree;
private List<MaterialCategoryVO> children;
}

View File

@ -15,5 +15,5 @@ public class MaterialCategoryQO {
/**
* 状态 0:不启用1启用
*/
private Integer enableState;
private Integer enableState = 1;
}

View File

@ -1,8 +1,10 @@
package com.nflg.wms.repository.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.nflg.wms.repository.handler.LtreeTypeHandler;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@ -17,7 +19,7 @@ import java.io.Serializable;
@Setter
@ToString
@Accessors(chain = true)
@TableName("qms_qc_material_category")
@TableName(value = "qms_qc_material_category", autoResultMap = true)
public class QmsQcMaterialCategory implements Serializable {
private static final long serialVersionUID = 1L;
@ -43,5 +45,6 @@ public class QmsQcMaterialCategory implements Serializable {
/**
* 父级树路径ltree类型
*/
@TableField(typeHandler = LtreeTypeHandler.class)
private String parentTree;
}

View File

@ -0,0 +1,36 @@
package com.nflg.wms.repository.handler;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.*;
/**
* 处理 PostgreSQL ltree 类型与 Java String 的映射
*/
@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.OTHER)
public class LtreeTypeHandler extends BaseTypeHandler<String> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setObject(i, parameter, Types.OTHER);
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName);
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex);
}
}

View File

@ -0,0 +1,97 @@
package com.nflg.wms.scheduled.processor;
import cn.hutool.core.collection.CollectionUtil;
import com.nflg.wms.common.pojo.dto.MaterialCategoryVO;
import com.nflg.wms.repository.entity.QmsQcMaterialCategory;
import com.nflg.wms.repository.service.IQmsQcMaterialCategoryService;
import com.nflg.wms.starter.service.BomMaterialService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import tech.powerjob.worker.core.processor.ProcessResult;
import tech.powerjob.worker.core.processor.TaskContext;
import tech.powerjob.worker.core.processor.sdk.BasicProcessor;
import tech.powerjob.worker.log.OmsLogger;
import java.util.ArrayList;
import java.util.List;
/**
* 从主物料同步物料分类到QMS
*/
@Component(value = "MaterialCategorySyncProcessor")
public class MaterialCategorySyncProcessor implements BasicProcessor {
@Resource
private BomMaterialService bomMaterialService;
@Resource
private IQmsQcMaterialCategoryService qmsQcMaterialCategoryService;
@Override
public ProcessResult process(TaskContext context) {
OmsLogger log = context.getOmsLogger();
try {
log.info("开始");
List<MaterialCategoryVO> categoryVOS = bomMaterialService.getCategory("");
categoryVOS = flattenCategories(categoryVOS);
log.info("共{}条", categoryVOS.size());
if (CollectionUtil.isNotEmpty(categoryVOS)) {
List<Long> existingIds = qmsQcMaterialCategoryService.lambdaQuery()
.select(QmsQcMaterialCategory::getId)
.list()
.stream()
.map(QmsQcMaterialCategory::getId)
.toList();
List<MaterialCategoryVO> newCategories = categoryVOS.stream()
.filter(categoryVO -> !existingIds.contains(categoryVO.getRowId()))
.toList();
log.info("其中新数据{}条", newCategories.size());
if (CollectionUtil.isNotEmpty(newCategories)) {
qmsQcMaterialCategoryService.saveBatch(newCategories.stream()
.map(categoryVO -> {
QmsQcMaterialCategory qmsQcMaterialCategory = new QmsQcMaterialCategory();
qmsQcMaterialCategory.setId(categoryVO.getRowId());
qmsQcMaterialCategory.setCategoryCode(categoryVO.getCategoryCode());
qmsQcMaterialCategory.setCategoryName(categoryVO.getCategoryName());
qmsQcMaterialCategory.setParentCategoryRowId(categoryVO.getParentCategoryRowId());
qmsQcMaterialCategory.setParentTree(categoryVO.getParentTree().replace(',','.'));
return qmsQcMaterialCategory;
})
.toList()
);
}
categoryVOS.removeAll(newCategories);
if (CollectionUtil.isNotEmpty(categoryVOS)){
qmsQcMaterialCategoryService.updateBatchById(categoryVOS.stream()
.map(categoryVO -> {
QmsQcMaterialCategory qmsQcMaterialCategory = new QmsQcMaterialCategory();
qmsQcMaterialCategory.setId(categoryVO.getRowId());
qmsQcMaterialCategory.setCategoryCode(categoryVO.getCategoryCode());
qmsQcMaterialCategory.setCategoryName(categoryVO.getCategoryName());
qmsQcMaterialCategory.setParentCategoryRowId(categoryVO.getParentCategoryRowId());
qmsQcMaterialCategory.setParentTree(categoryVO.getParentTree());
return qmsQcMaterialCategory;
})
.toList()
);
}
}
return new ProcessResult(true);
} catch (Exception ex) {
log.error("同步物料分类失败", ex);
return new ProcessResult(false, "同步物料分类失败");
}
}
private List<MaterialCategoryVO> flattenCategories(List<MaterialCategoryVO> categoryVOS) {
List<MaterialCategoryVO> result = new ArrayList<>();
for (MaterialCategoryVO category : categoryVOS) {
result.add(category);
if (CollectionUtil.isNotEmpty(category.getChildren())) {
result.addAll(flattenCategories(category.getChildren()));
category.setChildren(null);
}
}
return result;
}
}