Compare commits

...

3 Commits

Author SHA1 Message Date
xs 2d46cf13c5 1.3.0:
结构bom和物料bom后端完善
1 week ago
xs 463888b02f Merge remote-tracking branch 'origin/master' 1 week ago
xs 77a48167b5 1.2.9:
时序数据库tsdb支持1.x和2.x版本
2 weeks ago

@ -13,5 +13,7 @@ public interface HwMomMesConstants {
public static final Long MES_MATERIAL_BOM_TOP_FLAG_YES = 1L;
public static final String DELETE_FLAG_YES = "1";
public static final String DELETE_FLAG_NO = "0";
}

@ -0,0 +1,32 @@
package org.dromara.common.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @description mes
* @author xins
* @date 2025/3/24 10:33
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "mes.workshop")
public class MesProperties {
/**
* ID
*/
private Long semiFinishedId;
/**
* ID
*/
private Long modelingId;
/**
* ID
*/
private Long vulcanizingId;
}

@ -1,9 +1,11 @@
package org.dromara.mes;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.dromara.common.properties.MesProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
*
@ -12,6 +14,7 @@ import org.springframework.boot.context.metrics.buffering.BufferingApplicationSt
*/
@EnableDubbo
@SpringBootApplication
@EnableConfigurationProperties(MesProperties.class)
public class HwMomMesApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(HwMomMesApplication.class);

@ -7,6 +7,7 @@ import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.mes.domain.BaseMeasurementUnitInfo;
import org.dromara.mes.domain.ProdMaterialBom;
import org.dromara.mes.domain.ProdMaterialBomVersion;
import org.dromara.mes.domain.bo.*;
import org.dromara.mes.domain.vo.*;
@ -104,14 +105,27 @@ public class ProdMaterialBomController extends BaseController {
*
* @param materialBomIds
*/
// @SaCheckPermission("mes:materialBom:remove")
// @Log(title = "物料BOM信息", businessType = BusinessType.DELETE)
// @DeleteMapping("/{materialBomIds}")
// public R<Void> remove(@NotEmpty(message = "主键不能为空")
// @PathVariable Long[] materialBomIds) {
// return toAjax(prodMaterialBomService.deleteWithValidByIds(List.of(materialBomIds), true));
// }
/**
* BOM
*
* @param boList
*/
@SaCheckPermission("mes:materialBom:remove")
@Log(title = "物料BOM信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{materialBomIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] materialBomIds) {
return toAjax(prodMaterialBomService.deleteWithValidByIds(List.of(materialBomIds), true));
@PostMapping("/deleteMaterialBoms")
public R<Void> remove(@RequestBody List<ProdMaterialBomBo> boList) {
return toAjax(prodMaterialBomService.deleteMaterialBoms(boList));
}
/**
* BOM
*/

@ -72,6 +72,11 @@ public class BaseStructureBom extends TenantEntity {
*/
private String activeFlag;
/**
* 1 0
*/
private String deleteFlag;
/**
*
*/

@ -119,6 +119,11 @@ public class ProdMaterialBom extends TenantEntity {
*/
private String activeFlag;
/**
* 1 0
*/
private String deleteFlag;
/**
*
*/

@ -32,4 +32,8 @@ public class ProdMaterialBomVersion extends TenantEntity {
private String activeFlag;
/**
* bom
*/
private String bomVersionDesc;
}

@ -72,6 +72,11 @@ public class BaseStructureBomBo extends BaseEntity {
*/
private String activeFlag;
/**
* 1 0
*/
private String deleteFlag;
/**
*
*/

@ -119,6 +119,11 @@ public class ProdMaterialBomBo extends BaseEntity {
*/
private String activeFlag;
/**
* 1 0
*/
private String deleteFlag;
/**
*
*/

@ -32,5 +32,9 @@ public class ProdMaterialBomVersionBo extends BaseEntity {
@NotBlank(message = "激活标识1是 0否不能为空", groups = { AddGroup.class, EditGroup.class })
private String activeFlag;
/**
* bom
*/
private String bomVersionDesc;
}

@ -137,4 +137,6 @@ public class BaseStructureBomVo implements Serializable {
private List<BaseStructureBomVo> children = new ArrayList<BaseStructureBomVo>();
private String materialTypeCode;//join字段
private String parentMaterialTypeName;
}

@ -41,5 +41,9 @@ public class ProdMaterialBomVersionVo implements Serializable {
@ExcelDictFormat(readConverterExp = "1=是,0=否")
private String activeFlag;
/**
* bom
*/
private String bomVersionDesc;
}

@ -15,6 +15,7 @@ import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
@ -191,4 +192,25 @@ public class ProdMaterialBomVo implements Serializable {
private String unitName;//子物料单位
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
ProdMaterialBomVo that = (ProdMaterialBomVo) o;
return Objects.equals(parentId, that.parentId) && Objects.equals(materialId, that.materialId) && Objects.equals(unitId, that.unitId) && Objects.equals(parentUnitId, that.parentUnitId) && Objects.equals(parentStandardAmount, that.parentStandardAmount) && Objects.equals(materialTypeId, that.materialTypeId) && Objects.equals(parentMaterialTypeId, that.parentMaterialTypeId) && Objects.equals(materialBomVersion, that.materialBomVersion) && Objects.equals(standardAmount, that.standardAmount);
}
@Override
public int hashCode() {
return Objects.hash(parentId, materialId, unitId, parentUnitId, parentStandardAmount, materialTypeId, parentMaterialTypeId, materialBomVersion, standardAmount);
}
public boolean equalsToSource(ProdMaterialBom o) {
if (o == null) return false;
return Objects.equals(parentId, o.getParentId()) && Objects.equals(materialId, o.getMaterialId())
&& Objects.equals(unitId, o.getUnitId()) && Objects.equals(parentUnitId, o.getParentUnitId())
&& parentStandardAmount.compareTo(o.getParentStandardAmount())==0 && Objects.equals(materialTypeId, o.getMaterialTypeId())
&& Objects.equals(parentMaterialTypeId, o.getParentMaterialTypeId()) && Objects.equals(materialBomVersion, o.getMaterialBomVersion())
&& standardAmount.compareTo(o.getStandardAmount())==0;
}
}

@ -32,4 +32,7 @@ public interface BaseStructureBomMapper extends BaseMapperPlus<BaseStructureBom,
List<BaseStructureBomVo> selectStructureBomJoinMaterialTypeList(BaseStructureBomBo baseStructureBomBo);
List<BaseStructureBomVo> selectStructureBomRecursives(Long materialTypeId);
}

@ -58,6 +58,13 @@ public interface IProdMaterialBomService {
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* @param materialBomBos
* @return java.lang.Boolean
* @description BOM
*/
public Boolean deleteMaterialBoms(List<ProdMaterialBomBo> materialBomBos);
/**
* BOMBOM
* @param boList BOM

@ -21,6 +21,7 @@ import org.dromara.mes.domain.BaseClassTeamInfo;
import org.dromara.mes.domain.ProdMaterialBom;
import org.dromara.mes.domain.bo.BaseClassTeamInfoBo;
import org.dromara.mes.domain.vo.BaseClassTeamInfoVo;
import org.dromara.mes.domain.vo.ProdMaterialBomVo;
import org.dromara.mes.domain.vo.TreeSelect;
import org.dromara.mes.mapper.ProdMaterialBomMapper;
import org.springframework.stereotype.Service;
@ -31,6 +32,7 @@ import org.dromara.mes.mapper.BaseStructureBomMapper;
import org.dromara.mes.service.IBaseStructureBomService;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@ -175,32 +177,28 @@ public class BaseStructureBomServiceImpl implements IBaseStructureBomService {
throw new ServiceException("此物料类型下已经有此子级物料类型");
}
//TODO:需要找整棵树,不能无限循环
BaseStructureBom reverseQuery = new BaseStructureBom();//同一个物料类型同一个父级,反过来父级物料类型是物料类型的子级
reverseQuery.setParentId(entity.getMaterialTypeId());
reverseQuery.setMaterialTypeId(entity.getParentId());
if (baseMapper.selectCount(Wrappers.lambdaQuery(reverseQuery)) > 0) {
throw new ServiceException("已经存在此物料类型的父级物料类型是此子级物料类型");
List<BaseStructureBomVo> recursiveVos = baseMapper.selectStructureBomRecursives(entity.getParentId());
if (recursiveVos != null && !recursiveVos.isEmpty()) {
List<BaseStructureBomVo> filterVos = recursiveVos.stream().
filter(vo -> vo.getParentId().equals(entity.getMaterialTypeId()) || vo.getMaterialTypeId().equals(entity.getMaterialTypeId())).toList();
if (!filterVos.isEmpty()) {
throw new ServiceException("已经存在此物料类型的父级物料类型是此子级物料类型");
}
}
}
/**
* bom
* bom
*/
private boolean materialBomUsed(BaseStructureBomVo dbStructureBomVo){
//需要校验父级和子级都已经被引用,才算引用
private boolean materialBomUsed(BaseStructureBomVo dbStructureBomVo) {
//需要校验父级是否已经被引用
Long dbParentMaterialTypeId = dbStructureBomVo.getParentId();
Long dbMaterialTypeId = dbStructureBomVo.getMaterialTypeId();
ProdMaterialBom parentQuery = new ProdMaterialBom();
parentQuery.setMaterialTypeId(dbParentMaterialTypeId);
parentQuery.setParentMaterialTypeId(dbParentMaterialTypeId);
Long parentCount = prodMaterialBomMapper.selectCount(Wrappers.lambdaQuery(parentQuery));
ProdMaterialBom childQuery = new ProdMaterialBom();
childQuery.setMaterialTypeId(dbMaterialTypeId);
Long childCount = prodMaterialBomMapper.selectCount(Wrappers.lambdaQuery(childQuery));
return (parentCount > 0 && childCount > 0) ;
return parentCount > 0;
}
@ -214,16 +212,10 @@ public class BaseStructureBomServiceImpl implements IBaseStructureBomService {
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
for (Long id : ids) {
//监测删除的节点是否有子节点
BaseStructureBom query = new BaseStructureBom();
query.setParentId(id);
// if (baseMapper.selectCount(Wrappers.lambdaQuery(query)) > 0) {
// throw new ServiceException("BOM结构编号["+id+"]存在子节点,不允许删除");
// }
BaseStructureBomVo dbStructureBomVo = baseMapper.selectVoById(id);
for (Long structureBomId : ids) {
BaseStructureBomVo dbStructureBomVo = baseMapper.selectVoById(structureBomId);
if (materialBomUsed(dbStructureBomVo)) {
throw new ServiceException("BOM结构编号["+id+"]的物料类型和子级物料类型都已经在生产BOM中配置不允许删除");
throw new ServiceException("BOM结构编号[" + structureBomId + "]已经在生产BOM中配置不允许删除");
}
}
@ -255,17 +247,47 @@ public class BaseStructureBomServiceImpl implements IBaseStructureBomService {
*/
private List<BaseStructureBomVo> buildStructureBomTree(List<BaseStructureBomVo> structureBomVos) {
List<BaseStructureBomVo> returnList = new ArrayList<BaseStructureBomVo>();
List<Long> tempList = structureBomVos.stream().map(BaseStructureBomVo::getMaterialTypeId).collect(Collectors.toList());
for (BaseStructureBomVo structureBomVo : structureBomVos) {
// if (structureBomVo.getMaterialTypeId().equals(-1L) && StringUtil.isBlank(structureBomVo.getMaterialTypeName())) {
// structureBomVo.setMaterialTypeName("BOM结构");
// }
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(structureBomVo.getParentId())) {
recursionFn(structureBomVos, structureBomVo);
returnList.add(structureBomVo);
}
//1、先过滤出顶级
List<BaseStructureBomVo> topStructureBomVos = structureBomVos.stream()
.filter(obj -> structureBomVos.stream()
.noneMatch(other -> other.getMaterialTypeId().longValue() == obj.getParentId().longValue()))
.toList();
//2、过滤出parentId相同的
List<BaseStructureBomVo> distinctParentIdVoList = topStructureBomVos.stream()
.collect(Collectors.toMap(
BaseStructureBomVo::getParentId, // 以parentId作为key
Function.identity(), // 以对象本身作为value
(existing, replacement) -> existing // 如果遇到重复的key保留已有的对象
))
.values()
.stream()
.toList();
//3、基于过滤出顶级的进行递归
for (BaseStructureBomVo baseStructureBomVo : distinctParentIdVoList) {
BaseStructureBomVo topStructureBomVo = new BaseStructureBomVo();
topStructureBomVo.setStructureBomId(0L);
topStructureBomVo.setParentId(0L);
topStructureBomVo.setMaterialTypeId(baseStructureBomVo.getParentId());
topStructureBomVo.setMaterialTypeName(baseStructureBomVo.getParentMaterialTypeName());//设置parent的物料类型名称
structureBomVos.add(topStructureBomVo);
recursionFn(structureBomVos, topStructureBomVo);
returnList.add(topStructureBomVo);
}
// List<Long> tempList = structureBomVos.stream().map(BaseStructureBomVo::getMaterialTypeId).collect(Collectors.toList());
// for (BaseStructureBomVo structureBomVo : structureBomVos) {
//// if (structureBomVo.getMaterialTypeId().equals(-1L) && StringUtil.isBlank(structureBomVo.getMaterialTypeName())) {
//// structureBomVo.setMaterialTypeName("BOM结构");
//// }
// // 如果是顶级节点, 遍历该父节点的所有子节点
// if (!tempList.contains(structureBomVo.getParentId())) {
// recursionFn(structureBomVos, structureBomVo);
// returnList.add(structureBomVo);
// }
// }
if (returnList.isEmpty()) {
returnList = structureBomVos;
}

@ -1,13 +1,21 @@
package org.dromara.mes.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.dromara.common.constant.DatabaseConstants;
import org.dromara.common.constant.HwMomMesConstants;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.dromara.common.properties.MesProperties;
import org.dromara.mes.domain.ProdPlanInfo;
import org.dromara.mes.domain.bo.ProdPlanInfoBo;
import org.dromara.mes.domain.vo.ProdPlanInfoVo;
import org.dromara.mes.domain.vo.TreeSelect;
import org.dromara.mes.mapper.ProdPlanInfoMapper;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.dromara.mes.domain.bo.ProdMaterialBomBo;
import org.dromara.mes.domain.vo.ProdMaterialBomVo;
@ -36,6 +44,12 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
private final ProdMaterialBomMapper baseMapper;
private final ProdPlanInfoMapper prodPlanInfoMapper;
@Autowired
private MesProperties mesProperties;
/**
* BOM
*
@ -56,6 +70,7 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
*/
@Override
public List<ProdMaterialBomVo> queryList(ProdMaterialBomBo bo) {
bo.setDeleteFlag(HwMomMesConstants.DELETE_FLAG_NO);
MPJLambdaWrapper<ProdMaterialBom> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
@ -72,6 +87,7 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
.like(StringUtils.isNotBlank(bo.getMaterialBomVersion()), ProdMaterialBom::getMaterialBomVersion, bo.getMaterialBomVersion())
.eq(bo.getStandardAmount() != null, ProdMaterialBom::getStandardAmount, bo.getStandardAmount())
.eq(bo.getTopFlag() != null, ProdMaterialBom::getTopFlag, bo.getTopFlag())
.eq(bo.getDeleteFlag() != null, ProdMaterialBom::getDeleteFlag, bo.getDeleteFlag())
.eq(StringUtils.isNotBlank(bo.getCheckType()), ProdMaterialBom::getCheckType, bo.getCheckType())
.eq(bo.getProjectId() != null, ProdMaterialBom::getProjectId, bo.getProjectId())
.eq(bo.getAssembleTime() != null, ProdMaterialBom::getAssembleTime, bo.getAssembleTime())
@ -91,9 +107,8 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
@Override
public Boolean insertByBo(ProdMaterialBomBo bo) {
isTopFlag(bo);
ProdMaterialBomVo info = baseMapper.selectVoById(bo.getParentId());
ProdMaterialBom add = MapstructUtils.convert(bo, ProdMaterialBom.class);
validEntityBeforeSave(add);
validEntityUsed(bo);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setMaterialBomId(add.getMaterialBomId());
@ -110,16 +125,14 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
@Override
public Boolean updateByBo(ProdMaterialBomBo bo) {
ProdMaterialBom update = MapstructUtils.convert(bo, ProdMaterialBom.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
ProdMaterialBomVo dbProdMaterialBomVo = baseMapper.selectVoById(bo.getMaterialBomId());
if (!dbProdMaterialBomVo.equalsToSource(update)) {
validEntityUsed(bo);
return baseMapper.updateById(update) > 0;
}
return true;
}
/**
*
*/
private void validEntityBeforeSave(ProdMaterialBom entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* BOM
@ -143,6 +156,78 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
return baseMapper.deleteByIds(ids) > 0;
}
/**
* @param materialBomBos
* @return java.lang.Boolean
* @description BOM
*/
@Override
@Transactional (rollbackFor = Exception.class)
public Boolean deleteMaterialBoms(List<ProdMaterialBomBo> materialBomBos) {
Collection<Long> ids = new ArrayList<>();
materialBomBos.forEach(materialBomBo -> {
validEntityUsed(materialBomBo);
ProdMaterialBom update = MapstructUtils.convert(materialBomBo, ProdMaterialBom.class);
update.setDeleteFlag(HwMomMesConstants.DELETE_FLAG_YES);
baseMapper.updateById(update);
});
return true;
}
/**
*
*/
private void validEntityUsed(@NotNull ProdMaterialBomBo entity) {
Long semiFinishedId = mesProperties.getSemiFinishedId();
Long modelingId = mesProperties.getModelingId();
Long vulcanizingId = mesProperties.getVulcanizingId();
String semiFinishedTableName = DatabaseConstants.TABLE_NAME_PROD_PLAN_INFO_PREFIX + "_" + semiFinishedId;
String modelingTableName = DatabaseConstants.TABLE_NAME_PROD_PLAN_INFO_PREFIX + "_" + modelingId;
String vulcanizingTableName = DatabaseConstants.TABLE_NAME_PROD_PLAN_INFO_PREFIX + "_" + vulcanizingId;
ProdPlanInfoBo queryBo = new ProdPlanInfoBo();
queryBo.setMaterialId(entity.getParentId());
queryBo.setMaterialBomVersion(entity.getMaterialBomVersion());
MPJLambdaWrapper<ProdPlanInfo> lqw = buildPlanQueryWrapper(queryBo);
/**
* 使bom
*/
List<ProdPlanInfoVo> semiFinishedPlanInfoVos = prodPlanInfoMapper.selectProdPlanInfoList(semiFinishedTableName, lqw);
if (semiFinishedPlanInfoVos != null && !semiFinishedPlanInfoVos.isEmpty()) {
List<String> planCodes = semiFinishedPlanInfoVos.stream()
.map(ProdPlanInfoVo::getPlanCode)
.toList();
throw new ServiceException("半制品计划中计划编号[" + planCodes.toString() + "]已经使用此bom不能修改");
}
List<ProdPlanInfoVo> modelingPlanInfoVos = prodPlanInfoMapper.selectProdPlanInfoList(modelingTableName, lqw);
if (modelingPlanInfoVos != null && !modelingPlanInfoVos.isEmpty()) {
List<String> planCodes = modelingPlanInfoVos.stream()
.map(ProdPlanInfoVo::getPlanCode)
.toList();
throw new ServiceException("成型计划中计划编号[" + planCodes.toString() + "]已经使用此bom不能修改");
}
List<ProdPlanInfoVo> vulcanizingPlanInfoVos = prodPlanInfoMapper.selectProdPlanInfoList(vulcanizingTableName, lqw);
if (vulcanizingPlanInfoVos != null && !vulcanizingPlanInfoVos.isEmpty()) {
List<String> planCodes = vulcanizingPlanInfoVos.stream()
.map(ProdPlanInfoVo::getPlanCode)
.toList();
throw new ServiceException("硫化计划中计划编号已经使用[" + planCodes.toString() + "已经使用此bom不能修改");
}
}
/**
* SET
* BOM
@ -171,8 +256,8 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
if (CollUtil.isEmpty(boList)) {
return false;
}
//todo:在pojo中增加equals方法来判断有没有修改如果有修改则判断计划中是否有引用根据物料id和bom版本找
//TODO:判断在新建子级时是否存在在此颗树的父级节点存在此子级节点根据bom版本找
//判断在新建子级时是否存在在此颗树的父级节点存在此子级节点根据bom版本找(可以先不加此判断,主要原因是物料类型已经限制了)
//获取materialbomid不为空的更新获取materialbomid为空materialid不为空的保存
for (ProdMaterialBomBo prodMaterialBomBo : boList) {
if (prodMaterialBomBo.getMaterialBomId() == null) {
@ -213,7 +298,7 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
*/
@Override
public ProdMaterialBomVo selectParentMaterialBom(ProdMaterialBomBo bo) {
return baseMapper.selectParentMaterialBomJoin(bo);
return baseMapper.selectParentMaterialBomJoin(bo);
}
@ -238,15 +323,6 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
*/
private List<ProdMaterialBomVo> buildMaterialBomTree(List<ProdMaterialBomVo> prodMaterialBomVos) {
List<ProdMaterialBomVo> returnList = new ArrayList<ProdMaterialBomVo>();
// ProdMaterialBomVo topProdMaterialBomVo = new ProdMaterialBomVo();
// topProdMaterialBomVo.setMaterialId(0L);
// topProdMaterialBomVo.setMaterialName("生产BOM");
// topProdMaterialBomVo.setMaterialTypeId(1L);
// prodMaterialBomVos.add(topProdMaterialBomVo);
// List<Long> tempList = prodMaterialBomVos.stream().map(ProdMaterialBomVo::getMaterialId).toList();
/**
* parent
* v1AbcAparentId1materialIdA
@ -306,7 +382,6 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
}
/**
*
*
@ -365,4 +440,45 @@ public class ProdMaterialBomServiceImpl implements IProdMaterialBomService {
return getChildList(list, t).size() > 0 ? true : false;
}
private MPJLambdaWrapper<ProdPlanInfo> buildPlanQueryWrapper(ProdPlanInfoBo bo) {
Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<ProdPlanInfo> lqw = JoinWrappers.lambda(ProdPlanInfo.class)
.selectAll(ProdPlanInfo.class)
.eq(bo.getPlanId() != null, ProdPlanInfo::getPlanId, bo.getPlanId())
.eq(bo.getProductOrderId() != null, ProdPlanInfo::getProductOrderId, bo.getProductOrderId())
.eq(bo.getSaleOrderId() != null, ProdPlanInfo::getSaleOrderId, bo.getSaleOrderId())
.eq(StringUtils.isNotBlank(bo.getSaleorderCode()), ProdPlanInfo::getSaleorderCode, bo.getSaleorderCode())
.eq(StringUtils.isNotBlank(bo.getPlanCode()), ProdPlanInfo::getPlanCode, bo.getPlanCode())
.eq(StringUtils.isNotBlank(bo.getDispatchCode()), ProdPlanInfo::getDispatchCode, bo.getDispatchCode())
.eq(bo.getMaterialId() != null, ProdPlanInfo::getMaterialId, bo.getMaterialId())
.eq(bo.getMaterialBomVersion() != null, ProdPlanInfo::getMaterialBomVersion, bo.getMaterialBomVersion())
.eq(bo.getMaterialBomId() != null, ProdPlanInfo::getMaterialBomId, bo.getMaterialBomId())
.eq(bo.getProcessId() != null, ProdPlanInfo::getProcessId, bo.getProcessId())
.eq(bo.getProcessOrder() != null, ProdPlanInfo::getProcessOrder, bo.getProcessOrder())
.eq(bo.getLastProcessId() != null, ProdPlanInfo::getLastProcessId, bo.getLastProcessId())
.eq(StringUtils.isNotBlank(bo.getFinalProcessFlag()), ProdPlanInfo::getFinalProcessFlag, bo.getFinalProcessFlag())
.eq(StringUtils.isNotBlank(bo.getReleaseType()), ProdPlanInfo::getReleaseType, bo.getReleaseType())
.eq(bo.getReleaseId() != null, ProdPlanInfo::getReleaseId, bo.getReleaseId())
.eq(bo.getProductionTime() != null, ProdPlanInfo::getProductionTime, bo.getProductionTime())
.eq(bo.getPlanAmount() != null, ProdPlanInfo::getPlanAmount, bo.getPlanAmount())
.eq(bo.getDispatchAmount() != null, ProdPlanInfo::getDispatchAmount, bo.getDispatchAmount())
.eq(bo.getCompleteAmount() != null, ProdPlanInfo::getCompleteAmount, bo.getCompleteAmount())
.eq(bo.getPlanBeginTime() != null, ProdPlanInfo::getPlanBeginTime, bo.getPlanBeginTime())
.eq(bo.getPlanEndTime() != null, ProdPlanInfo::getPlanEndTime, bo.getPlanEndTime())
.eq(bo.getRealBeginTime() != null, ProdPlanInfo::getRealBeginTime, bo.getRealBeginTime())
.eq(bo.getRealEndTime() != null, ProdPlanInfo::getRealEndTime, bo.getRealEndTime())
.eq(StringUtils.isNotBlank(bo.getAttachId()), ProdPlanInfo::getAttachId, bo.getAttachId())
.eq(StringUtils.isNotBlank(bo.getPlanStatus()), ProdPlanInfo::getPlanStatus, bo.getPlanStatus())
.eq(StringUtils.isNotBlank(bo.getImportFlag()), ProdPlanInfo::getImportFlag, bo.getImportFlag())
.eq(StringUtils.isNotBlank(bo.getFinishFlag()), ProdPlanInfo::getFinishFlag, bo.getFinishFlag())
.eq(bo.getPriority() != null, ProdPlanInfo::getPriority, bo.getPriority())
.eq(bo.getShiftId() != null, ProdPlanInfo::getShiftId, bo.getShiftId())
.eq(bo.getClassTeamId() != null, ProdPlanInfo::getClassTeamId, bo.getClassTeamId())
.eq(StringUtils.isNotBlank(bo.getModelCode()), ProdPlanInfo::getModelCode, bo.getModelCode())
.in(StringUtils.isNotNull(bo.getPlanIds()), ProdPlanInfo::getPlanId, bo.getPlanIds())
.orderByDesc(ProdPlanInfo::getCreateTime);
return lqw;
}
}

@ -35,9 +35,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bsb.create_time,
bsb.update_time,
bmt.matrial_type_code as material_type_code,
bmt.matrial_type_name as material_type_name
bmt.matrial_type_name as material_type_name,
bmtf.matrial_type_name as parent_material_type_name
from base_structure_bom bsb
left join base_material_type bmt on bsb.material_type_id = bmt.matrial_type_id
left join base_material_type bmtf on bsb.parent_id = bmtf.matrial_type_id
<where>
<if test="materialTypeCode != null and materialTypeCode != ''">and bmt.matrial_type_code like concat('%', #{materialTypeCode},
'%')
@ -52,4 +54,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</select>
<select id="selectStructureBomRecursives" resultType="BaseStructureBomVo">
WITH RecursiveCTE AS (
SELECT
material_type_id,
parent_id,
tenant_id
FROM
base_structure_bom
WHERE
(material_type_id = #{materialTypeId} OR parent_id = #{materialTypeId})
UNION ALL
SELECT
m.material_type_id,
m.parent_id,
m.tenant_id
FROM
base_structure_bom m
INNER JOIN
RecursiveCTE r ON m.material_type_id = r.parent_id
)
SELECT material_type_id,
parent_id,
tenant_id FROM RecursiveCTE
</select>
</mapper>

@ -26,6 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join base_material_info bmip on pmb.parent_id=bmip.material_id
left join base_material_type bmtp on pmb.parent_material_type_id = bmtp.matrial_type_id
<where>
and pmb.delete_flag='0'
<if test="materialTypeCode != null and materialTypeCode != ''">and bmt.matrial_type_code like concat('%', #{materialTypeCode},
'%')
</if>
@ -52,7 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
pmb.parent_unit_id,
bmt.matrial_type_name as parent_material_type_name
from base_material_info bmi
left join prod_material_bom pmb on pmb.parent_id=bmi.material_id and pmb.material_bom_version = #{materialBomVersion}
left join prod_material_bom pmb on pmb.parent_id=bmi.material_id and pmb.material_bom_version = #{materialBomVersion} and pmb.delete_flag='0'
left join base_material_type bmt on bmi.material_type_id = bmt.matrial_type_id
<where>
<if test="parentId != null ">and bmi.material_id = #{parentId}</if>
@ -76,7 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join base_material_info bmi on pmb.parent_id=bmi.material_id
left join base_material_type bmt on bmi.parent_material_type_id = bmt.matrial_type_id
<where>
and pmb.delete_flag='0'
<if test="topFlag != null ">and pmb.top_flag = #{topFlag}</if>
</where>
@ -97,7 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
bmt.matrial_type_code as material_type_code,
bmt.matrial_type_name as material_type_name
from base_structure_bom bsb
left join prod_material_bom pmb on pmb.material_type_id = bsb.material_type_id and pmb.parent_id = #{parentId} and pmb.material_bom_version=#{materialBomVersion}
left join prod_material_bom pmb on pmb.material_type_id = bsb.material_type_id and pmb.parent_id = #{parentId} and pmb.material_bom_version=#{materialBomVersion} and pmb.delete_flag='0'
left join base_material_info bmi on pmb.material_id=bmi.material_id
left join base_material_type bmt on bsb.material_type_id = bmt.matrial_type_id
<where>

@ -38,6 +38,11 @@
<version>2.23</version>
</dependency>
<dependency>
<groupId>com.influxdb</groupId>
<artifactId>influxdb-client-java</artifactId>
<version>6.12.0</version> <!-- 请使用最新版本 -->
</dependency>
<!-- RuoYi Common Log -->
<dependency>

@ -0,0 +1,30 @@
package org.dromara.tsdb.component;
import java.util.List;
import java.util.Map;
public interface InfluxDbClient {
/**
*
* @param measurement
* @param tags
* @param fields
*/
void writeData(String measurement, Map<String, String> tags, Map<String, Object> fields);
/**
*
* @param measurement
* @param tags
* @param fields
* @param timestamp
*/
void writeData(String measurement, Map<String, String> tags, Map<String, Object> fields, long timestamp);
/**
*
* @param query
* @return
*/
List<Map<String, Object>> queryData(String query);
}

@ -0,0 +1,86 @@
package org.dromara.tsdb.component.impl;
import com.influxdb.client.domain.WritePrecision;
import org.dromara.tsdb.component.InfluxDbClient;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.influxdb.dto.Point;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
public class InfluxDb1xClientImpl implements InfluxDbClient {
private final InfluxDB influxDB;
public InfluxDb1xClientImpl(
@Value("${influxdb.url}") String url,
@Value("${influxdb.username}") String username,
@Value("${influxdb.password}") String password,
@Value("${influxdb.database}") String database) {
this.influxDB = InfluxDBFactory.connect(url, username, password);
this.influxDB.setDatabase(database);
}
@Override
public void writeData(String measurement, Map<String, String> tags, Map<String, Object> fields) {
Point.Builder pointBuilder = Point.measurement(measurement);
tags.forEach(pointBuilder::tag);
// 处理 fields确保类型正确
fields.forEach((key, value) -> {
if (value instanceof Number) {
pointBuilder.addField(key, (Number) value);
} else if (value instanceof String) {
pointBuilder.addField(key, (String) value);
} else if (value instanceof Boolean) {
pointBuilder.addField(key, (Boolean) value);
} else {
throw new IllegalArgumentException("Unsupported field type: " + value.getClass().getName());
}
});
influxDB.write(pointBuilder.build());
}
@Override
public void writeData(String measurement, Map<String, String> tags, Map<String, Object> fields, long timestamp) {
Point.Builder pointBuilder = Point.measurement(measurement).time(timestamp, TimeUnit.MILLISECONDS);
tags.forEach(pointBuilder::tag);
// 处理 fields确保类型正确
fields.forEach((key, value) -> {
if (value instanceof Number) {
pointBuilder.addField(key, (Number) value);
} else if (value instanceof String) {
pointBuilder.addField(key, (String) value);
} else if (value instanceof Boolean) {
pointBuilder.addField(key, (Boolean) value);
} else {
throw new IllegalArgumentException("Unsupported field type: " + value.getClass().getName());
}
});
influxDB.write(pointBuilder.build());
}
@Override
public List<Map<String, Object>> queryData(String query) {
QueryResult result = influxDB.query(new Query(query));
return result.getResults().stream()
.flatMap(r -> r.getSeries().stream())
.flatMap(s -> s.getValues().stream())
.map(values -> {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < values.size(); i++) {
System.out.println("values: " + values.get(i));
}
return map;
})
.toList();
}
}

@ -0,0 +1,88 @@
package org.dromara.tsdb.component.impl;
import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.InfluxDBClientFactory;
import com.influxdb.client.WriteApi;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.Point;
import com.influxdb.query.FluxRecord;
import com.influxdb.query.FluxTable;
import org.dromara.tsdb.component.InfluxDbClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class InfluxDb2xClientImpl implements InfluxDbClient {
private final InfluxDBClient influxDBClient;
private final String bucket;
public InfluxDb2xClientImpl(
@Value("${influxdb.url}") String url,
@Value("${influxdb.token}") String token,
@Value("${influxdb.org}") String org,
@Value("${influxdb.bucket}") String bucket) {
this.influxDBClient = InfluxDBClientFactory.create(url, token.toCharArray(), org, bucket);
this.bucket = bucket;
}
@Override
public void writeData(String measurement, Map<String, String> tags, Map<String, Object> fields) {
try (WriteApi writeApi = influxDBClient.getWriteApi()) {
Point point = Point.measurement(measurement);
tags.forEach(point::addTag);
// 处理 fields确保类型正确
fields.forEach((key, value) -> {
if (value instanceof Number) {
point.addField(key, (Number) value);
} else if (value instanceof String) {
point.addField(key, (String) value);
} else if (value instanceof Boolean) {
point.addField(key, (Boolean) value);
} else {
throw new IllegalArgumentException("Unsupported field type: " + value.getClass().getName());
}
});
writeApi.writePoint(point);
}
}
@Override
public void writeData(String measurement, Map<String, String> tags, Map<String, Object> fields,long timestamp) {
try (WriteApi writeApi = influxDBClient.getWriteApi()) {
Point point = Point.measurement(measurement)
.time(timestamp,WritePrecision.MS);//设置时间戳
tags.forEach(point::addTag);
// 处理 fields确保类型正确
fields.forEach((key, value) -> {
if (value instanceof Number) {
point.addField(key, (Number) value);
} else if (value instanceof String) {
point.addField(key, (String) value);
} else if (value instanceof Boolean) {
point.addField(key, (Boolean) value);
} else {
throw new IllegalArgumentException("Unsupported field type: " + value.getClass().getName());
}
});
writeApi.writePoint(point);
}
}
@Override
public List<Map<String, Object>> queryData(String query) {
List<FluxTable> tables = influxDBClient.getQueryApi().query(query);
return tables.stream()
.flatMap(table -> table.getRecords().stream())
.map(record -> {
Map<String, Object> map = new HashMap<>();
record.getValues().forEach((key, value) -> map.put(key, value));
return map;
})
.toList();
}
}

@ -1,7 +1,8 @@
package org.dromara.tsdb.config;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.dromara.tsdb.component.InfluxDbClient;
import org.dromara.tsdb.component.impl.InfluxDb1xClientImpl;
import org.dromara.tsdb.component.impl.InfluxDb2xClientImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -9,22 +10,22 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class InfluxDbConfig {
@Value("${influxdb.url}")
private String influxDBUrl;
@Value("${influxdb.version}")
private String version;
@Value("${influxdb.username}")
private String username;
@Value("${influxdb.password}")
private String password;
@Value("${influxdb.database}")
private String database;
@Value("${influxdb.bucket}")
private String bucket;
@Bean
public InfluxDB influxDB() {
InfluxDB influxDB = InfluxDBFactory.connect(influxDBUrl, username, password);
influxDB.setDatabase(database);
return influxDB;
public InfluxDbClient influxDbClient(
InfluxDb1xClientImpl influxDb1xClient,
InfluxDb2xClientImpl influxDb2xClient) {
if ("1.x".equals(version)) {
return influxDb1xClient;
} else if ("2.x".equals(version)) {
return influxDb2xClient;
} else {
throw new IllegalArgumentException("Unsupported InfluxDB version: " + version);
}
}
}

@ -6,6 +6,9 @@ import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/influx")
public class InfluxDbController {
@ -18,7 +21,7 @@ public class InfluxDbController {
*/
@PostMapping("/write")
public String writeData(@RequestBody InfluxMeasurementBo influxMeasurementBo) {
influxDbService.writeData(influxMeasurementBo);
influxDbService.writeData();
return "Data written to InfluxDB successfully!";
}
@ -26,7 +29,8 @@ public class InfluxDbController {
*
*/
@GetMapping("/query")
public QueryResult queryData(@RequestParam String query) {
return influxDbService.queryData(query);
public List<Map<String, Object>> queryData(@RequestParam String query) {
return influxDbService.queryData();
}
}

@ -3,19 +3,12 @@ package org.dromara.tsdb.service;
import org.dromara.tsdb.domain.bo.InfluxMeasurementBo;
import org.influxdb.dto.QueryResult;
import java.util.List;
import java.util.Map;
public interface IInfluxDbService {
/**
* InfluxDB
* @param influxMeasurementBo
*/
public void writeData(InfluxMeasurementBo influxMeasurementBo);
public void writeData();
/**
*
*
* @param query
* @return
*/
public QueryResult queryData(String query);
public List<Map<String, Object>> queryData();
}

@ -1,5 +1,6 @@
package org.dromara.tsdb.service.impl;
import org.dromara.tsdb.component.InfluxDbClient;
import org.dromara.tsdb.domain.bo.InfluxMeasurementBo;
import org.dromara.tsdb.service.IInfluxDbService;
import org.influxdb.InfluxDB;
@ -9,38 +10,52 @@ import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class InfluxDbServiceImpl implements IInfluxDbService {
@Autowired
private InfluxDB influxDB;
private InfluxDbClient influxDbClient;
/**
* InfluxDB
* @param influxMeasurementBo
*/
@Override
public void writeData(InfluxMeasurementBo influxMeasurementBo) {
Point point = Point.measurement(influxMeasurementBo.getMeasurement())
.tag(influxMeasurementBo.getTagKey(), influxMeasurementBo.getTagValue())
.addField(influxMeasurementBo.getFieldKey(), influxMeasurementBo.getFieldValue())
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS)
.build();
influxDB.write(point);
public void writeData() {
Map<String, String> tags = Map.of("device_id", "device331");
Map<String, Object> fields = Map.of("value", 33.6);
influxDbClient.writeData("temperature", tags, fields);
}
/**
*
*
* @param query
* @return
*/
@Override
public QueryResult queryData(String query) {
QueryResult queryResult = influxDB.query(new Query(query));
System.out.println(queryResult.getResults());
return queryResult;
public List<Map<String, Object>> queryData() {
String query = "from(bucket: \"hwmom\") |> range(start: -7d) |> filter(fn: (r) => r._measurement == \"temperature\")";
List<Map<String, Object>> queryData= influxDbClient.queryData(query);
StringBuilder sb = new StringBuilder();
int index = 1;
for(Map<String, Object> map : queryData) {
if(map == null) {
sb.append("发现空Map对象\n\n");
continue;
}
sb.append("第").append(index++).append("条记录:\n");
for(Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
sb.append(" ").append(key)
.append(" = ")
.append(value != null ? value.toString() : "null")
.append("\n");
}
sb.append("\n");
}
System.out.println(sb.toString());
return queryData;
}
}

Loading…
Cancel
Save